1001 Interesting Integers
http://www.tzcoder.cn/acmhome/problemdetail.do?&method=showdetail&id=4731
给你[a,b]区间,问有几个数是有趣的数(数字只有一个数不同的),臣妾不行;
1002 Longest Prefix
http://www.tzcoder.cn/acmhome/problemdetail.do?&method=showdetail&id=3559
1003 Count Color
http://www.tzcoder.cn/acmhome/problemdetail.do?&method=showdetail&id=6036
t种颜色上到原色为颜色1的板子上面。线段树
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=100005; 5 ll add[maxn<<2]; 6 ll ans[maxn<<2]; 7 void update(int rt) 8 { 9 ans[rt]=ans[rt<<1]|ans[rt<<1|1]; 10 } 11 void Push(int rt) 12 { 13 if(add[rt]) 14 { 15 add[rt<<1]=add[rt]; 16 add[rt<<1|1]=add[rt]; 17 ans[rt<<1]=add[rt]; 18 ans[rt<<1|1]=add[rt]; 19 add[rt]=0; 20 } 21 } 22 void buildtree(int left,int right,int rt) 23 { 24 add[rt]=0; 25 if(left==right) 26 { 27 ans[rt]=1; 28 return; 29 } 30 int mid=(left+right)>>1; 31 buildtree(left,mid,rt<<1); 32 buildtree(mid+1,right,rt<<1|1); 33 update(rt); 34 } 35 void updatetree(int a,int b,int c,int Left,int Right,int rt) 36 { 37 if(a<=Left&&b>=Right) 38 { 39 add[rt]=1<<(c-1); 40 ans[rt]=1<<(c-1); 41 return; 42 } 43 Push(rt); 44 int mid=(Left+Right)>>1; 45 if(a<=mid) updatetree(a,b,c,Left,mid,rt<<1); 46 if(mid<b) updatetree(a,b,c,mid+1,Right,rt<<1|1); 47 update(rt); 48 } 49 ll query(int a,int b,int Left,int Right,int rt) 50 { 51 if(a<=Left&&b>=Right) return ans[rt]; 52 Push(rt); 53 int mid=(Left+Right)>>1; 54 ll res=0; 55 if(a<=mid) res|=query(a,b,Left,mid,rt<<1); 56 if(mid<b) res|=query(a,b,mid+1,Right,rt<<1|1); 57 return res; 58 } 59 int main() 60 { 61 int L,T,O;scanf("%d%d%d",&L,&T,&O); 62 buildtree(1,L,1); 63 while(O--) 64 { 65 getchar(); 66 char ch;scanf("%c",&ch); 67 if(ch=='C') 68 { 69 int a,b,c;scanf("%d%d%d",&a,&b,&c); 70 if(a>b) swap(a,b); 71 updatetree(a,b,c,1,L,1); 72 } 73 else{ 74 int a,b;scanf("%d%d",&a,&b); 75 if(a>b) swap(a,b); 76 ll res=query(a,b,1,L,1); 77 ll num=0; 78 while(res) 79 { 80 if(res&1) num++; 81 res>>=1; 82 } 83 printf("%lld ",num); 84 } 85 } 86 }
1004 Get Many Persimmon Trees
http://www.tzcoder.cn/acmhome/problemdetail.do?&method=showdetail&id=6045
二维树状数组,以(s,t)的矩形暴力找过去,得到最大的ans。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 #define N 105 5 int ma[N][N]; 6 int n,m; 7 inline int lowbit(int x){return x&-x;} 8 void updata(int x,int y) 9 { 10 for(int i=x;i<=n;i+=lowbit(i)) 11 for(int j=y;j<=m;j+=lowbit(j)) ma[i][j]++; 12 } 13 int query(int x,int y) 14 { 15 int res=0; 16 for(int i=x;i>0;i-=lowbit(i)) 17 for(int j=y;j>0;j-=lowbit(j)) res+=ma[i][j]; 18 return res; 19 } 20 int main() 21 { 22 int T; 23 while(~scanf("%d",&T),T) 24 { 25 scanf("%d%d",&n,&m); 26 memset(ma,0,sizeof(ma)); 27 while(T--) 28 { 29 int a,b;scanf("%d%d",&a,&b); 30 updata(a,b); 31 } 32 int s,t;scanf("%d%d",&s,&t); 33 int ans=0; 34 for(int i=1;i<=n;i++) 35 for(int j=1;j<=m;j++) 36 { 37 int upi=i,upj=j,downi=i+s-1,downj=j+t-1; 38 if(downi>n||downj>m) continue; 39 int sum=query(upi-1,upj-1)+query(downi,downj)-query(downi,upj-1)-query(upi-1,downj); 40 ans=ans>sum?ans:sum; 41 } 42 printf("%d ",ans); 43 } 44 }
1005 Travelling
http://www.tzcoder.cn/acmhome/problemdetail.do?&method=showdetail&id=6062
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 #define N 60005 5 int mp[11][11],n,m,ans,dp[11][N]; 6 int in[11],three[11]; 7 void init(int n) 8 { 9 for(int i=0;i<n;i++) 10 { 11 for(int j=0;j<in[n];j++) 12 dp[i][j]=-1; 13 for(int j=0;j<n;j++) 14 mp[i][j]=-1; 15 } 16 } 17 int arr(int three[],int sum) 18 { 19 int res=0; 20 for(int i=0;i<n;i++) 21 { 22 three[i]=sum%3; 23 sum/=3; 24 if(three[i]) res++; 25 } 26 return res; 27 } 28 void bfs() 29 { 30 for(int kk=1;kk<in[n];kk++) 31 { 32 int k=arr(three,kk); 33 for(int i=0;i<n;i++) 34 { 35 if(three[i]) 36 { 37 if(k==1) dp[i][kk]=0; 38 if(dp[i][kk]==-1) continue; 39 if(k==n) 40 { 41 if(ans==-1) ans=dp[i][kk]; 42 else ans=min(ans,dp[i][kk]); 43 } 44 for(int j=0;j<n;j++) 45 { 46 if(i!=j&&three[j]<2&&mp[i][j]!=-1) 47 { 48 int mark=kk+in[j]; 49 if(dp[j][mark]==-1) dp[j][mark]=dp[i][kk]+mp[i][j]; 50 else dp[j][mark]=min(dp[i][kk]+mp[i][j],dp[j][mark]); 51 } 52 } 53 } 54 } 55 } 56 } 57 int main() 58 { 59 in[0]=1; 60 for(int i=1;i<=10;i++) in[i]=in[i-1]*3; 61 while(~scanf("%d%d",&n,&m)) 62 { 63 init(n); 64 while(m--) 65 { 66 int a,b,c;scanf("%d%d%d",&a,&b,&c); 67 a--,b--; 68 if(mp[a][b]!=-1) mp[a][b]=mp[b][a]=min(mp[a][b],c); 69 else mp[a][b]=mp[b][a]=c; 70 } 71 ans=-1; 72 bfs(); 73 printf("%d ",ans); 74 } 75 }
1006 A/B
http://www.tzcoder.cn/acmhome/problemdetail.do?&method=showdetail&id=6065
(A/B)%MOD->(A%MOD)*(B-1%MOD)
这里用了求出m的欧拉函数值再进行一次快速幂f(b,phi[M]-1)求逆元
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int M=9973; 4 typedef long long ll; 5 ll phi[100005]; 6 void euler() 7 { 8 for(int i=1;i<=M;++i) 9 phi[i]=i; 10 for (int i=2;i<=M;i++) 11 if (phi[i]==i) 12 for (int j=i;j<=M;j+=i) 13 phi[j]=phi[j]/i*(i-1); 14 } 15 ll f(ll a,ll b) 16 { 17 ll res=1,x=a%M; 18 while(b) 19 { 20 if(b&1) res=(res*x)%M; 21 b>>=1; 22 x=x*x%M; 23 } 24 return res; 25 } 26 int main() 27 { 28 euler(); 29 int t;scanf("%d",&t); 30 while(t--) 31 { 32 ll n,b;scanf("%lld%lld",&n,&b); 33 printf("%lld ",n*f(b,phi[M]-1)%M); 34 } 35 }
拓展欧几里得算法,a*x+b*y=GCD,当a==GCD,b==0时停止查找,可推出最后状态a*1+b*0==GCD。前后等式分别为a*x+b*y=gcd、b*x1+(a%b)*y1=gcd,补上条件递归。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int M=9973; 5 ll ans,re; 6 void e_gcd(ll a,ll b) 7 { 8 if(b==0) 9 { 10 ans=1,re=0; 11 return; 12 } 13 e_gcd(b,a%b); 14 ll temp=ans; 15 ans=re; 16 re=temp-a/b*re; 17 } 18 int main() 19 { 20 int t;scanf("%d",&t); 21 while(t--) 22 { 23 ll n,b;scanf("%lld%lld",&n,&b); 24 e_gcd(b,M); 25 ans<0?ans+=M:ans+=0; 26 printf("%lld ",n*ans%M); 27 } 28 }
1007 Road Construction
http://www.tzcoder.cn/acmhome/problemdetail.do?&method=showdetail&id=6085
缩点,(叶子节点+1)/2
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 #define N 1005 5 vector<int> G[N]; 6 int n,r,low[N],degree[N],mp[N][N],cnt; 7 void init() 8 { 9 for(int i=1;i<=n;i++) G[i].clear(); 10 memset(low,0,sizeof(low)); 11 memset(degree,0,sizeof(degree)); 12 memset(mp,0,sizeof(mp)); 13 } 14 void dfs(int u,int x) 15 { 16 int l=G[u].size(); 17 low[u]=cnt++; 18 for(int i=0;i<l;i++) 19 { 20 int v=G[u][i]; 21 if(v==x) continue; 22 if(!low[v]) dfs(v,u); 23 low[u]=min(low[u],low[v]); 24 } 25 } 26 int tarjan() 27 { 28 for(int i=1;i<=n;i++) 29 { 30 int l=G[i].size(); 31 for(int j=0;j<l;j++) 32 if(low[i]!=low[G[i][j]]) degree[low[i]]++; 33 } 34 int res=0; 35 for(int i=1;i<=n;i++) 36 if(degree[i]==1) res++; 37 return res; 38 } 39 int main() 40 { 41 scanf("%d%d",&n,&r); 42 init(); 43 while(r--) 44 { 45 int a,b;scanf("%d%d",&a,&b); 46 if(mp[a][b]) continue; 47 mp[a][b]=mp[b][a]=1; 48 G[a].push_back(b),G[b].push_back(a); 49 } 50 cnt=1; 51 dfs(1,0); 52 int res=tarjan(); 53 printf("%d ",(res+1)/2); 54 }
1008 Currency Exchange
http://www.tzcoder.cn/acmhome/problemdetail.do?&method=showdetail&id=6097
spfa算法,判断是否存在环路。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 #define N 105 5 double ma1[N][N],ma2[N][N],ans[N]; 6 int n,m,s,a,b; 7 int vis[N]; 8 double v,x_ab,x_ba,y_ab,y_ba; 9 bool spfa() 10 { 11 ans[s]=v; 12 vis[s]=1; 13 queue<int> qu; 14 qu.push(s); 15 while(!qu.empty()) 16 { 17 int node=qu.front(); 18 qu.pop(); 19 vis[node]=0; 20 for(int i=1;i<=n;i++) 21 { 22 if(ans[i]<(ans[node]-ma2[node][i])*ma1[node][i]) 23 { 24 ans[i]=(ans[node]-ma2[node][i])*ma1[node][i]; 25 if(ans[s]>v) return true; 26 if(!vis[i]) qu.push(i),vis[i]=1; 27 } 28 } 29 } 30 return false; 31 } 32 void init() 33 { 34 memset(vis,0,sizeof(vis)); 35 for(int i=1;i<=n;i++) 36 { 37 for(int j=1;j<=n;j++) 38 { 39 ma1[i][j]=1; 40 ma2[i][j]=ma1[i][j]=0; 41 } 42 } 43 } 44 int main() 45 { 46 scanf("%d%d%d%lf",&n,&m,&s,&v); 47 init(); 48 for(int kk=0;kk<m;kk++) 49 { 50 scanf("%d%d%lf%lf%lf%lf",&a,&b,&x_ab,&y_ab,&x_ba,&y_ba); 51 ma1[a][b]=x_ab,ma2[a][b]=y_ab; 52 ma1[b][a]=x_ba,ma2[b][a]=y_ba; 53 } 54 if(spfa()) printf("YES "); 55 else printf("NO "); 56 }