bestcoder杯回顾
题目列表:hdu5214~5223
5214:
当时第一反应是由递推公式推出通项公式,事实证明这就是作!大!死!
因为通项公式是这样的:L[n]=a^(n-1)*(b+L[1])-b
于是就需要快速幂。然而用了快速幂还是慢。。。【实际上是被卡在了7000ms多一点点。。。】
其实直接放到数组里一项一项递推就行。。速度并不慢还省事
另外本题还有一个point:被mod的那个数字很奇怪,所以直接用unsigned int存就行。不仅省空间还不用mod了(溢出相当于自动mod)
当时没想起来这个于是用了long long,于是数组存不下,于是T^T
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #define LL unsigned int 5 //#define MOD 4294967296 6 using namespace std; 7 LL N,L1,R1,a,b,c,d,T; 8 LL ll[10000010],rr[10000010]; 9 LL li,ri; 10 11 int main() 12 { 13 scanf("%d",&T); 14 while(T--) 15 { 16 scanf("%d%d%d%d%d%d%d",&N,&L1,&R1,&a,&b,&c,&d); 17 ll[1]=L1; rr[1]=R1; 18 if(L1>R1) swap(L1,R1); 19 LL minl=L1,minr=R1,maxl=L1,maxr=R1; 20 for(LL i=2;i<=N;i++) 21 { 22 ll[i]=ll[i-1]*a+b; 23 rr[i]=rr[i-1]*c+d; 24 li=ll[i],ri=rr[i]; 25 if(li>ri) swap(li,ri); 26 if (ri<minr) 27 { 28 minl=li; 29 minr=ri; 30 } 31 if (li>maxl) 32 { 33 maxl=li; 34 maxr=ri; 35 } 36 } 37 bool ok=false; 38 //cout<<minl<<","<<minr<<" "<<maxl<<","<<maxr<<endl; 39 for(LL i=1;i<=N;i++) 40 { 41 li=ll[i]; ri=rr[i]; 42 if(li>ri) swap(li,ri); 43 //cout<<li<<","<<ri<<endl; 44 if((li>minr)&&(ri<maxl)) 45 { 46 ok=true; 47 break; 48 } 49 } 50 if (ok) printf("YES\n"); else printf("NO\n"); 51 } 52 return 0; 53 }
5222:
并查集+拓扑排序
对于双向边联通的那些点,可以看作一个点。(因为它们任意两点之间都可以到达)
最后把这个union作为一个点,和剩下的单向边放一起构图。然后拓扑排序判断有没有环。
1 #pragma comment(linker, "/STACK:102400000,102400000") 2 #include <iostream> 3 #include <cstdio> 4 #include<vector> 5 #include<cstring> 6 using namespace std; 7 #define MAXN 10000000 8 int f[MAXN]; //father 9 int d[MAXN]; //->i 10 int nxt[MAXN]; 11 int head[MAXN]; 12 int ev[MAXN]; 13 int cnt; 14 int N,M1,M2,T,x,y; 15 16 int find(int x) 17 { 18 if (f[x]!=x) 19 f[x]=find(f[x]); 20 return f[x]; 21 } 22 23 void iunion(int x,int y) 24 { 25 int fx,fy; 26 fx=find(x); 27 fy=find(y); 28 if (fx!=fy) 29 f[fx]=fy; 30 } 31 32 void addedge(int x,int y) //x->y 33 { 34 d[y]++; //d[i]:点i的入度 35 ev[cnt]=y; //ev[i]:第i条边的destination 36 nxt[cnt]=head[x]; //nxt[i]:第i条边的下一条边 37 head[x]=cnt; //head[i]:由i节点出发的第一条边的序号 38 cnt++; 39 } 40 41 void topsort() 42 { 43 int res=0; 44 vector<int>vec; 45 for(int i=1; i<=N; i++) 46 if(i==find(i)) 47 { 48 ++res; 49 if(d[i]==0) 50 vec.push_back(i); 51 } 52 for(int i=0; i<vec.size(); i++) 53 { 54 int u=vec[i]; 55 for(int j=head[u]; ~j; j=nxt[j]) 56 { 57 int v=ev[j]; 58 d[v]--; 59 if(!d[v]) 60 vec.push_back(v); 61 } 62 } 63 int last=vec.size(); 64 if(last!=res) 65 printf("YES\n"); 66 else printf("NO\n"); 67 } 68 69 int main() 70 { 71 cin>>T; 72 while(T--) 73 { 74 scanf("%d%d%d",&N,&M1,&M2); 75 for(int i=1; i<=N; i++) f[i]=i; 76 bool ok=false; 77 for(int i=1; i<=M1; i++) 78 { 79 scanf("%d%d",&x,&y); 80 int fx=find(x),fy=find(y); 81 if(fx==fy) ok=true; 82 else f[fx]=fy; 83 } 84 cnt=0; 85 memset(d,0,sizeof(d)); 86 memset(head,-1,sizeof(head)); 87 for(int i=1; i<=M2; i++) 88 { 89 scanf("%d%d",&x,&y); 90 int tx=find(x),ty=find(y); 91 addedge(tx,ty); 92 } 93 if(ok) 94 { 95 printf("YES\n"); 96 } 97 else 98 topsort(); 99 100 } 101 102 return 0; 103 }
5223:
这题当时交给队友了。。。。
题意:给出若干L,R,A,表示gcd(p[L],p[L+1],...,p[R])=A。要求解出原数组p[]
sol:首先来看几个有代表性的情况:
1 9 7 1 9 6 1 9 8 1 9 3 1 9 4 1 9 8 1 5 3
2 5 3 2 5 4 2 5 4 2 5 7 2 5 6 2 5 4 2 7 7
stupid stupid stupid stupid stupid ok ok
对所有的L,R,A,令p[i]=lcm(p[i],A)(L<=i<=R)。最后再验证一遍
其实最后验证的时候求区间的gcd可以用优化的方法(类似RMQ的那个)。本题数据小懒得用了= =
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 #define LL long long 6 7 LL p[1010]; //array 8 int L[1010],R[1010]; //Li,Ri 9 LL A[1010]; //Ansi 10 int T,N,Q; 11 12 LL gcd(LL a,LL b) //辗转相除法,返回gcd(a,b) 13 { 14 if (b==0) return a; 15 return gcd(b,a%b); 16 } 17 18 LL lcm(LL a,LL b) 19 { 20 LL t=gcd(a,b); 21 t=a*b/t; 22 return t; 23 } 24 25 LL ggcd(int l,int r) 26 { 27 LL aa=p[l]; 28 for(int i=l+1;i<=r;i++) 29 aa=gcd(aa,p[i]); 30 return aa; 31 } 32 33 LL llcm(int l,int r) 34 { 35 LL aa=p[l]; 36 for(int i=l+1;i<=r;i++) 37 aa=lcm(aa,p[i]); 38 return aa; 39 } 40 41 int main() 42 { 43 scanf("%d",&T); 44 while(T--) 45 { 46 scanf("%d%d",&N,&Q); 47 for(int i=0;i<=1000;i++)p[i]=1; 48 for(int i=1;i<=Q;i++) 49 { 50 scanf("%d%d%I64d",&L[i],&R[i],&A[i]); 51 //LL t=llcm(L[i],R[i]); 52 //t=lcm(t,A[i]); 53 for(int j=L[i];j<=R[i];j++) 54 p[j]=lcm(p[j],A[i]); 55 //p[j]=t; 56 } 57 bool ok=true; 58 for (int i=1;i<=Q;i++) 59 { 60 LL t=ggcd(L[i],R[i]); 61 // printf("%d,%d = %I64d\n",L[i],R[i],t); 62 if (t!=A[i]) ok=false; 63 } 64 // for(int i=1;i<=N;i++) 65 // printf("%d ",p[i]); 66 // printf("\n"); 67 if(ok) 68 { 69 for(int i=1;i<N;i++) 70 printf("%I64d ",p[i]); 71 printf("%I64d\n",p[N]); 72 } 73 else 74 printf("Stupid BrotherK!\n"); 75 } 76 return 0; 77 }
posted on 2015-05-14 17:40 Pentium.Labs 阅读(272) 评论(0) 编辑 收藏 举报