聽說難度不大的四道題,結果暴力都被打崩了.....c++
第一題就是大水題了,預處理一波知足條件的花的數,再一遍循環求一個前綴和,而後輸入什麼O(1)作個減法就成了;git
總時間複雜度O(t)數組
1 #include<bits/stdc++.h> 2 using namespace std; 3 int t,l,r; 4 int flow[100100]; 5 int sumf[100100]; 6 char buf[1<<15],*fs,*ft; 7 inline char getc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;} 8 inline int read() 9 { 10 int x=0,f=1; char ch=getc(); 11 while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getc();} 12 while(isdigit(ch)) {x=x*10+ch-'0'; ch=getc();} 13 return x*f; 14 } 15 void put(int x) 16 { 17 if(x==0){putchar('0'); putchar('\n'); return;} 18 if(x<0){putchar('-'); x=-x;} 19 int num=0; 20 char ch[16]; 21 while(x) ch[++num]=x%10+'0',x/=10; 22 while(num) putchar(ch[num--]); 23 putchar('\n'); 24 } 25 inline int abss(int a,int b){return a-b>0?a-b:b-a;} 26 void work() 27 { 28 int xx,yy,k; 29 for(int i=1;i<=100001;i++) 30 { 31 xx=yy=0; 32 k=i; 33 while(k) 34 { 35 if(k%6==1) xx++; 36 k/=6; 37 } 38 k=i; 39 while(k) 40 { 41 if(k%9==1) yy++; 42 k/=9; 43 } 44 if(abss(xx,yy)<2) flow[i]=1; 45 } 46 for(int i=1;i<=100001;i++) 47 { 48 sumf[i]=sumf[i-1]+flow[i]; 49 } 50 return; 51 } 52 int main() 53 { 54 work(); 55 t=read(); 56 for(int i=1;i<=t;i++) 57 { 58 l=read(); 59 r=read(); 60 put(sumf[r]-sumf[l-1]); 61 } 62 return 0; 63 }
第二題就是暴力錯的第一題,原思路是每次比賽都sort,結果最後一行打成for(int i=1;i<=n;){if(a[i].xx==1)printf("%d %d",i,a[i].v);break;}我選擇撞牆...........spa
事實上不用sort這種O(nlogn)確定會超時的排序,由於每次的增量只有一半的人增,且最可能是1,因此只會涉及到最多o(n)次左右交換,但第一次排序仍是要sort一下 設計
目測複雜度是O(nr)的code
#include<bits/stdc++.h> using namespace std; int n; struct gamer { int v,p,xx; }a[1000010]; int r; char buf[1<<15],*fs,*ft; inline char getc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;} inline int read() { int x=0,f=1; char ch=getc(); while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getc();} while(isdigit(ch)) {x=x*10+ch-'0'; ch=getc();} return x*f; } bool mycmp(gamer a,gamer b){return a.v==b.v?a.xx<b.xx:a.v>b.v;} int main() { n=read(); n=n*2; for(register int i=1;i<=n;++i) { a[i].v=read(); a[++i].v=read(); } for(register int i=1;i<=n;++i) { a[i].p=read(); a[i].xx=i; a[++i].p=read(); a[i].xx=i; } r=read(); sort(a+1,a+1+n,mycmp); for(register int i=1;i<=r;++i) { for(register int j=1;j<=n;j+=2){a[j].p>a[j+1].p?a[j].v++:a[j+1].v++;} for(register int j=1;j<n;j++) { register int k=j;while(k&&(a[k].v<a[k+1].v||a[k].v==a[k+1].v&&a[k].xx>a[k+1].xx)) { swap(a[k].v,a[k+1].v);swap(a[k].p,a[k+1].p);swap(a[k].xx,a[k+1].xx);--k;}//核心就是這幾句了 } } sort(a+1,a+1+n,mycmp); for(register int i=1;i<=n;++i){if(a[i].xx==1){ printf("%d %d",i,a[i].v);break;}} return 0; }
湊合看吧...........blog
第三題先跳過(由於還沒改完(逃))排序
第四題,樹狀數組打的暴力居然全炸了......一個數據都不過.......get
好吧不說暴力,只需掃一遍,對於每一個數,找一下左邊連續比他大的,右邊連續比他大的,小的也同樣,而後左長度*右長度*這個數就是它對答案的貢獻,大就是正小就是負it
複雜度的話....100000的隨機數據是能夠的,精心設計過的就可能會炸......
這玩意過不了300000的數據,300000的話就只能上單調棧了......
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n; 4 int a[100100]; 5 inline int read() 6 { 7 int num=0,f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 8 while(isdigit(ch)){num=num*10+ch-'0';ch=getchar();} 9 return num*f; 10 } 11 int main() 12 { 13 n=read(); 14 register int i=1; 15 for(;i<=n;++i){a[i]=read();} 16 long long ans=0; 17 for(i=1;i<=n;++i) 18 { 19 register int k=i-1; 20 long long l=1,r=1; 21 while(a[k]>a[i]&&k>0) {--k;++l;} 22 k=i+1; 23 while(a[k]>=a[i]&&k<=n) {++k;++r;} 24 ans-=l*r*a[i]; 25 k=i-1; 26 l=1,r=1; 27 while(a[k]<a[i]&&k>0){--k;++l;} 28 k=i+1; 29 while(a[k]<=a[i]&&k<=n){++k;++r;} 30 ans+=l*r*a[i]; 31 } 32 cout<<ans; 33 return 0; 34 }