2019/11/09 TZOJ

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\n",num);
84         }
85     }
86 }
View Code

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\n",ans);
43     }
44 }
View Code

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\n",ans);
74     }
75 }
View Code

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",n*f(b,phi[M]-1)%M);
34     }
35 }
View Code

拓展欧几里得算法,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",n*ans%M);
27     }
28 }
View Code

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\n",(res+1)/2);
54 }
View Code

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\n");
55     else printf("NO\n");
56 }
View Code

猜你喜欢

转载自www.cnblogs.com/Aaaamber/p/11837916.html