• 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
    ",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
    ",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
    ",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*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*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
    ",(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
    ");
    55     else printf("NO
    ");
    56 }
    View Code
  • 相关阅读:
    【散列表】拉链法以及线性探查法
    【Spring】第一个hello world程序
    『Java基础』基本数据类型和包装类
    二进制、八进制、十进制、十六进制互转
    [MyBatis]缓存机制
    Ora-01830 日期格式图片在转换整个输入字符串之前结束
    leetcode1584. 连接所有点的最小费用(最小生成树算法的应用)
    VS安装SVN插件
    Winform打开不窗体设计器解决方法(Winform以普通C#类显示,打开不了设计器)
    Oracle修改System密码并解锁
  • 原文地址:https://www.cnblogs.com/Aaaamber/p/11837916.html
Copyright © 2020-2023  润新知