据说难度不大的四道题,结果暴力都被打崩了.....
第一题就是大水题了,预处理一波满足条件的花的数,再一遍循环求一个前缀和,然后输入什么O(1)做个减法就成了;
总时间复杂度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(' '); 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(' '); 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;}我选择撞墙...........
事实上不用sort这种O(nlogn)肯定会超时的排序,因为每次的增量只有一半的人增,且最多是1,所以只会涉及到最多o(n)次左右交换,但第一次排序还是要sort一下
目测复杂度是O(nr)的
#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; }
凑合看吧...........
第三题先跳过(因为还没改完(逃))
第四题,树状数组打的暴力竟然全炸了......一个数据都不过.......
好吧不说暴力,只需扫一遍,对于每个数,找一下左边连续比他大的,右边连续比他大的,小的也一样,然后左长度*右长度*这个数就是它对答案的贡献,大就是正小就是负
复杂度的话....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 }