A. City Day 用了st表//是否是麻煩了 ios
建表而後O(1)查詢這個數前面x個數的最小值和後面y個數的最小值,注意邊界和x,y爲0的狀況。c++
1 #include<bits/stdc++.h> 2 #include<iostream> 3 #include<stack> 4 #include<algorithm> 5 #include<cstdio> 6 #include<cmath> 7 #include<cstring> 8 #define mem(a) memset(a,0,sizeof(a)) 9 #define memm(a) memset(a,inf,sizeof(a)) 10 #define ll long long 11 #define ld long double 12 #define uL unsigned long long 13 #define pb push_back 14 #define inf 0x3f3f3f3f 15 using namespace std; 16 const int N=1e5+5; 17 const int M=100+5; 18 int n,m,k,a[N],b[N],x,y; 19 int cnt,sum,mx,st[N][25]; 20 void findm() 21 { 22 for(int i=0;i<n;i++) {st[i][0]=a[i];} 23 for(int j=1;j<25;j++) 24 for(int i=0;i<n;i++) 25 if(i+(1<<(j-1))<n) 26 st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]); 27 } 28 int query(int l,int r) 29 { 30 if(l>r) return inf; 31 int len=log2(r-l+1); 32 return min(st[l][len],st[r-(1<<len)+1][len]); 33 } 34 int main() 35 { 36 cin>>n>>x>>y; 37 for(int i=0;i<n;i++) 38 cin>>a[i]; 39 findm(); 40 for(int i=0;i<n;i++) 41 { 42 if(query(max(0,i-x),max(0,i-1))>a[i] || i==0) 43 { 44 if((a[i]<query(min(n-1,i+1),min(n-1,i+y)))||i==n-1) 45 { 46 cout<<i+1<<endl; 47 return 0; 48 } 49 } 50 } 51 return 0; 52 }
我真傻,真的。就怕tle的,沒想到暴力還真過了,狗屎,悲劇,痛不欲生,果真不能對A題當心呵護,要霸王直上麼(′д` )…彡…彡 //最狗的是,時間還更快。數組
1 #include<bits/stdc++.h> 2 #include<iostream> 3 #include<stack> 4 #include<algorithm> 5 #include<cstdio> 6 #include<cmath> 7 #include<cstring> 8 #define fio ios::sync_with_stdio(false);cin.tie(0) 9 #define mem(a) memset(a,0,sizeof(a)) 10 #define memm(a) memset(a,inf,sizeof(a)) 11 #define ll long long 12 #define ld long double 13 #define uL unsigned long long 14 #define pb push_back 15 #define inf 0x3f3f3f3f 16 using namespace std; 17 const int N=1e5+5; 18 const int M=1e9+5; 19 int n,m,k,x,a[N],y,vis[N]; 20 int main() 21 { 22 cin>>n>>x>>y; 23 for(int i=1;i<=n;i++) 24 cin>>a[i]; 25 for(int i=1;i<=n;i++) 26 { 27 int f=0; 28 for(int j=i-1;j>max(0,i-x-1);j--) 29 if(a[j]<a[i]) {f=1;break;} 30 for(int j=i+1;j<min(n+1,i+y+1);j++) 31 if(a[j]<a[i]) {f=1;break;} 32 if(f==0) {cout<<i<<endl;break;} 33 } 34 return 0; 35 }
在double上錯了好幾回,太傻了,並且最開始沒看到等腰,更傻了(ノへ ̄、) 函數
再一次,發現不是被double坑了,而是,被h和l的類型。。。 設成double或者ll就能夠了,這個原理,,ui
1 int main() 2 { 3 ll h,l; 4 scanf("%I64d%I64d",&h,&l); 5 printf("%.13f\n", (l*l-h*h)/2.0/h ); 6 return 0; 7 }
C. MP3 spa
//不知道是否是想的太麻煩了,時間要800多,晚點再看看 ---》好吧,加了fio就從800到200了orzcode
先判斷是否知足,不知足就找臨界的那個點,對數函數移項(記得要用種數減),而後枚舉l,獲得最小d的消費數(把a排序,l的前面+r的後面的數)。blog
tips:①用v保存每種數第一個數的下標,這以前a排個序。 ②仔細讀題,向上取整(嗚呼) 排序
1 #include<bits/stdc++.h> 2 #define fio ios::sync_with_stdio(false);cin.tie(0) 3 #define ll long long 4 #define pb push_back 5 #define inf 0x3f3f3f3f 6 using namespace std; 7 const int N=4e5+5; 8 int n,m,I,k,a[N],b[N],mx,x,y,ans; 9 vector<int>v; 10 int f(int l,int r) 11 { 12 if(l>r) return inf; 13 if(r==v.size()-1) return v[l]-1; 14 return v[l]+n-v[r+1]; 15 16 } 17 int quickpow(int a,int n) 18 { 19 int ans=1; 20 while(n) 21 { 22 if(n&1) ans*=a; 23 n>>=1; 24 a*=a; 25 } 26 return ans; 27 } 28 int inter(int m) 29 { 30 return (log2(m)!=int(log2(m)))?log2(m)+1:log2(m); 31 } 32 int main() 33 { 34 fio; 35 cin>>n>>I; 36 I*=8; 37 for(int i=1;i<=n;i++) 38 cin>>a[i]; 39 sort(a+1,a+n+1); 40 int now=-1,id=0; 41 for(int i=1;i<=n;i++) 42 { 43 if(a[i]!=now) 44 { 45 id=i; 46 now=a[i]; 47 v.pb(id); 48 } 49 } 50 k=v.size(); 51 ans=(inter(k)*n)-I; 52 if(ans<=0) 53 { 54 cout<<0<<endl; 55 return 0; 56 } 57 int need=inf; 58 ans=k-quickpow(2,I/n); 59 for(int i=0;i<=ans;i++) 60 need=min(f(i,k-ans+i-1),need); 61 cout<<need<<endl; 62 return 0; 63 }
//一樣的代碼,就算加了fio,cin也比scanf慢400多呀
原本想着要不要線段樹或者分塊的,可是以爲太麻煩了,單純的數組就能夠了。全部統一改的用all記錄,取最大,用b記錄此次詢問修改的值;用vis標記單獨改的,值存第幾回詢問,這裏取最後一次修改這個值的次序;再來個數組記錄從最後一次詢問往前的修改最大值。最後輸出就沒單獨修改過的和all比,另外一個和b[修改次序+1]比.
1 #include<bits/stdc++.h> 2 #include<iostream> 3 #include<stack> 4 #include<algorithm> 5 #include<cstdio> 6 #include<cmath> 7 #include<cstring> 8 #define fio ios::sync_with_stdio(false);cin.tie(0) 9 #define mem(a) memset(a,0,sizeof(a)) 10 #define memm(a) memset(a,inf,sizeof(a)) 11 #define ll long long 12 #define ld long double 13 #define uL unsigned long long 14 #define pb push_back 15 #define inf 0x3f3f3f3f 16 using namespace std; 17 const int N=2e5+5; 18 const int M=1e9+5; 19 int n,m,k,x,a[N],q,y,b[N],vis[N]; 20 int main() 21 { 22 fio; 23 cin>>n; 24 for(int i=1;i<=n;i++) 25 cin>>a[i]; 26 cin>>k; 27 for(int i=1;i<=k;i++) 28 { 29 cin>>q>>x; 30 if(q==1) 31 { 32 cin>>y; 33 a[x]=y; 34 vis[x]=i; 35 } 36 else 37 { 38 m=max(m,x); 39 b[i]=x; 40 } 41 } 42 for(int i=k-1;i>=1;i--) 43 b[i]=max(b[i],b[i+1]); 44 for(int i=1;i<=n;i++) 45 { 46 if(!vis[i]) 47 cout<<max(a[i],m)<<" "; 48 else 49 cout<<max(b[vis[i]],a[i])<<" "; 50 } 51 cout<<endl; 52 return 0; 53 }
E. Matching vs Independent Set
//我的理解,有誤望指正<(_ _)>
題意是找n個邊或點,邊要知足任意兩條邊沒有公共點(匹配邊),點要知足任意兩點沒有直達邊(獨立點),要注意點總共有3*n個。
根據數學知識,咱們能夠獲得,邊最多有(3*n)*(3*n-1)/2條(簡單圖,無平行邊),而匹配邊最多有3*n/2條(如n=2,一種狀況是1-2,3-4,5-6),獨立點最多有3*n-1個(樣例3)
若某兩條邊有公共點,那除了公共點以外的兩點相互獨立,是獨立點;若是沒有公共點,就成兩條匹配邊;因此匹配邊和獨立點是此消彼長的。因此!不存在Impossible的狀況,必定是Matching或IndSet或二者都有的狀況.大概就是匹配邊就算減到沒影了,獨立點自己個數加上隨着增長的也夠n個了。
1 #include<bits/stdc++.h> 2 #define fio ios::sync_with_stdio(false);cin.tie(0) 3 #define mem(a) memset(a,0,sizeof(a)) 4 #define memm(a) memset(a,inf,sizeof(a)) 5 #define ll long long 6 #define pb push_back 7 #define inf 0x3f3f3f3f 8 using namespace std; 9 const int N=5e5+5; 10 const int M=1e9+5; 11 int n,m,k,a,b,vis[N]; 12 int main() 13 { 14 fio; 15 int t; 16 cin>>t; 17 for(int k=1;k<=t;k++) 18 { 19 cin>>n>>m; 20 vector<int>num; 21 for(int i=1;i<=m;i++) 22 { 23 cin>>a>>b; 24 if(vis[a]!=k&&vis[b]!=k) 25 { 26 num.pb(i); 27 vis[a]=vis[b]=k; //用1的話,每次k變化都要從新清零 28 } 29 } 30 if(num.size()>=n) 31 { 32 cout << "Matching"<<endl; 33 for(int i=0;i<n;i++) 34 cout<<num[i]<<" "; 35 } 36 else 37 { 38 cout << "IndSet"<<endl; 39 int now=0; 40 for(int i=1;i<=3*n;i++) 41 { 42 if(vis[i]!=k) cout<<i<<" ",now++; 43 if(now==n) break; 44 } 45 } 46 cout<<endl; 47 } 48 49 return 0; 50 }