• codeforces #601 (div 1) 做题记录


    A.

    显然构造一个蛇形就行了

    复杂度(O(r*c))

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define ull unsigned long long
     4 #define pii pair<int,int>
     5 #define pll pair<long long,long long>
     6 #define mpr(a,b) make_pair(a,b) 
     7 #define maxn 105
     8 using namespace std;
     9 ll gcd(ll a,ll b){if(!b)return a;return gcd(b,a%b);}
    10 ll fastpow(ll a,ll p,ll mod)
    11 {
    12     ll ans=1;
    13     while(p)
    14     {
    15         if(p&1)ans=ans*a%mod;
    16         a=a*a%mod;p>>=1;
    17     }
    18     return ans;
    19 }
    20 ll inv(ll x,ll mod){return fastpow(x,mod-2,mod);} 
    21 int T,n,m,k;
    22 char a[maxn][maxn];
    23 int Ans[maxn][maxn];
    24 int nx[maxn][maxn],ny[maxn][maxn];
    25 char ID(int x)
    26 {
    27     if(1<=x&&x<=26)return x-1+'a';
    28     if(27<=x&&x<=52)return x-27+'A';
    29     if(53<=x&&x<=62)return x-53+'0';
    30 }
    31 int main()
    32 {
    33     scanf("%d",&T);
    34     while(T--)
    35     {
    36         scanf("%d%d%d",&n,&m,&k);
    37         for(int i=0;i<=n+1;++i)
    38             for(int j=0;j<=m+1;++j)nx[i][j]=ny[i][j]=Ans[i][j]=0;
    39         for(int i=1;i<=n;++i)
    40         {
    41             for(int j=1;j<=m;++j)nx[i][j]=i,ny[i][j]=(i&1)?j+1:j-1;
    42             if(i&1)nx[i][m]=i+1,ny[i][m]=m;
    43             else nx[i][1]=i+1,ny[i][1]=1;
    44         }
    45         for(int i=1;i<=n;++i)scanf("%s",a[i]+1);
    46         int num=0;
    47         for(int i=1;i<=n;++i)
    48             for(int j=1;j<=m;++j)if(a[i][j]=='R')num++;
    49         int t=num/k;
    50         int k1=num-t*k;
    51         int k2=k-k1;
    52         int nowx=1,nowy=1;
    53         for(int p=1;p<=k1;++p)
    54         {
    55             int cnt=0;
    56             while(cnt<t+1)
    57             {
    58                 Ans[nowx][nowy]=p;
    59                 if(a[nowx][nowy]=='R')cnt++;
    60                 int xx=nx[nowx][nowy],yy=ny[nowx][nowy];
    61                 nowx=xx,nowy=yy;
    62             }
    63         }
    64         for(int p=k1+1;p<=k1+k2;++p)
    65         {
    66             int cnt=0;
    67             while(cnt<t)
    68             {
    69                 Ans[nowx][nowy]=p;
    70                 if(a[nowx][nowy]=='R')cnt++;
    71                 int xx=nx[nowx][nowy],yy=ny[nowx][nowy];
    72                 nowx=xx,nowy=yy;
    73             } 
    74         }
    75         while(nowx&&nowy)
    76         {
    77             Ans[nowx][nowy]=k1+k2;
    78             int xx=nx[nowx][nowy],yy=ny[nowx][nowy];
    79             nowx=xx,nowy=yy;
    80         }
    81         for(int i=1;i<=n;++i)
    82         { 
    83             for(int j=1;j<=m;++j)printf("%c",ID(Ans[i][j]));
    84             puts("");
    85         } 
    86     }
    87 }
    View Code

    B.

    设总和为(tot),则我们考虑枚举(tot)的约数,然后check

    假设这个约数是(k)

    check做法:先把每个数 ( mod k),然后把一段一段和为(k)的段抠出来

    然后枚举移动到的位置,取最优

    这样B1就做完了,复杂度(O(n*d(w)))

    然后发现B2的(tot)太大,约数太多,因此我们只需要考虑枚举其质因子即可

    复杂度(O(n log w))

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define ull unsigned long long
     4 #define pii pair<int,int>
     5 #define pll pair<long long,long long>
     6 #define mpr(a,b) make_pair(a,b)
     7 using namespace std;
     8 ll gcd(ll a,ll b){if(!b)return a;return gcd(b,a%b);}
     9 ll fastpow(ll a,ll p,ll mod)
    10 {
    11     ll ans=1;
    12     while(p)
    13     {
    14         if(p&1)ans=ans*a%mod;
    15         a=a*a%mod;p>>=1;
    16     }
    17     return ans;
    18 }
    19 ll inv(ll x,ll mod){return fastpow(x,mod-2,mod);}
    20 #define maxn 1000005 
    21 int n;
    22 ll tot,a[maxn],ans;
    23 ll b[maxn],c[maxn];
    24 void check(ll k)
    25 {
    26     ll res=0,tt=0;
    27     vector<pll> v;
    28     for(int i=1;i<=n;++i)b[i]=a[i]%k,tt+=b[i],c[i]=b[i];
    29     ll K=tt/k;
    30     int j=1;
    31     for(int i=1;i<=K;++i)
    32     {
    33         v.clear();
    34         ll sx=0,sy=0,num=0;
    35         while(j<=n&&num<=k)
    36         {
    37             if(b[j]>0)
    38             {
    39                 ll tmp=min(b[j],k-num);
    40                 v.push_back(mpr(j,tmp)),sy+=j*tmp,num+=tmp;
    41                 b[j]-=tmp;
    42             }
    43             if(num==k)break;
    44             j++;
    45         }
    46         ll t=(ll)5e18;
    47         if(v.size())
    48         {
    49             ll s=0;
    50             for(int p=0;p<v.size();++p)
    51             {
    52                 ll pos=v[p].first;
    53                 t=min(t,1ll*pos*s-sx+sy-1ll*(k-s)*pos);
    54                 sx+=pos*v[p].second;sy-=pos*v[p].second;
    55                 s+=v[p].second;
    56             }
    57             res+=t;
    58         }
    59     }
    60     ans=min(ans,res);
    61 }
    62 int main()
    63 {
    64     scanf("%d",&n);
    65     for(int i=1;i<=n;++i)scanf("%I64d",&a[i]),tot+=a[i];
    66     if(tot==1)
    67     {
    68         puts("-1");
    69         return 0;
    70     }
    71     ans=(ll)5e18;
    72     ll x=tot;
    73     for(ll i=2;i*i<=tot;++i)if(x%i==0)
    74     {
    75         while(x%i==0)x/=i;
    76         check(i);
    77     }
    78     if(x>1)check(x);
    79     cout<<ans<<endl;
    80 }
    View Code

    C.

    固定1,2两个点,然后利用(n)次叉积问出其他点在((1,2))这条线的哪一侧

    然后再用(n)次面积问出两边最大面积点

    最后问每个点在最大面积点的哪边,然后sort一下就可以了

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 int n;
     5 vector<ll> A,B;
     6 ll s[1005];
     7 vector<ll> X,Y,Z,W;
     8 ll ask(ll t,ll i,ll j,ll k)
     9 {
    10     ll x;
    11     cout<<t<<" "<<i<<" "<<j<<" "<<k<<endl;
    12     fflush(stdout);
    13     cin>>x;
    14     return x;
    15 }
    16 bool cmp1(int x,int y)
    17 {
    18     return s[x]<s[y];
    19 }
    20 bool cmp2(int x,int y)
    21 {
    22     return s[x]>s[y];
    23 }
    24 int main()
    25 {
    26     cin>>n;
    27     for(int i=3;i<=n;++i)
    28     {
    29         ll x=ask(2,1,i,2);
    30         if(x>0)A.push_back(i);
    31         else B.push_back(i);
    32     }
    33     ll ida=0,sa=0,idb=0,sb=0;
    34     for(ll x:A)
    35     {
    36         ll y=ask(1,1,x,2);
    37         s[x]=y;
    38         if(y>sa)ida=x,sa=y;
    39     }
    40     for(ll x:B)
    41     {
    42         ll y=ask(1,1,x,2);
    43         s[x]=y;
    44         if(y>sb)idb=x,sb=y;
    45     }
    46     for(ll x:A)if(x!=ida)
    47     {
    48         ll y=ask(2,1,x,ida);
    49         if(y<0)Y.push_back(x);
    50         else X.push_back(x);
    51     }
    52     for(ll x:B)if(x!=idb)
    53     {
    54         ll y=ask(2,1,x,idb);
    55         if(y<0)W.push_back(x);
    56         else Z.push_back(x);
    57     }
    58     sort(X.begin(),X.end(),cmp1);
    59     sort(Y.begin(),Y.end(),cmp2);
    60     sort(Z.begin(),Z.end(),cmp1);
    61     sort(W.begin(),W.end(),cmp2);
    62     cout<<0<<" ";
    63     cout<<1<<" ";
    64     for(ll x:X)cout<<x<<" ";
    65     if(ida)cout<<ida<<" ";
    66     for(ll x:Y)cout<<x<<" ";
    67     cout<<2<<" ";
    68     for(ll x:Z)cout<<x<<" ";
    69     if(idb)cout<<idb<<" ";
    70     for(ll x:W)cout<<x<<" ";
    71 }
    View Code

    D.

    考虑一种暴力做法:

    对于修改操作,对点(u)枚举和他相邻的点(v),那么就是这个子树(subtree(v))加(frac{(n-size[v])}{n}*d)

    然后我们考虑提出根之后就是dfs序上一段区间加,可以线段树维护

    但是这个在点度数大的时候会GG

    那么考虑Bigsmall

    把大度数的点当做关键点,这些点不用线段树维护,暴力打标记

    然后暴力爬关键点统计标记

      1 #include<bits/stdc++.h>
      2 #define ll long long
      3 #define ull unsigned long long
      4 #define pii pair<int,int>
      5 #define pll pair<long long,long long>
      6 #define mpr(a,b) make_pair(a,b)
      7 #define maxn 300005
      8 using namespace std;
      9 ll gcd(ll a,ll b){if(!b)return a;return gcd(b,a%b);}
     10 ll fastpow(ll a,ll p,ll mod)
     11 {
     12     ll ans=1;
     13     while(p)
     14     {
     15         if(p&1)ans=ans*a%mod;
     16         a=a*a%mod;p>>=1;
     17     }
     18     return ans;
     19 }
     20 ll inv(ll x,ll mod){return fastpow(x,mod-2,mod);}
     21 const ll mod = 998244353;
     22 int n,q;
     23 vector<int> g[maxn];
     24 int f[maxn],top[maxn];
     25 int lpos[maxn],rpos[maxn],cnt,sz[maxn];
     26 ll addt[maxn];
     27 const int B = 100;
     28 void dfs(int u,int fa)
     29 {
     30     if(g[fa].size()>B)top[u]=u;
     31     else top[u]=top[fa];
     32     f[u]=fa;
     33     lpos[u]=++cnt; 
     34     sz[u]=1;
     35     for(int v:g[u])if(v!=fa)
     36     {
     37         dfs(v,u);
     38         sz[u]+=sz[v];
     39     }
     40     rpos[u]=cnt;
     41 }
     42 ll val[maxn<<2];
     43 void add(int rt,int l,int r,int ql,int qr,ll v)
     44 {
     45     if(ql>qr)return;
     46     if(ql<=l&&r<=qr)
     47     {
     48         val[rt]=(val[rt]+v)%mod;
     49         return;
     50     }
     51     int mid=(l+r)>>1;
     52     if(ql<=mid)add(rt<<1,l,mid,ql,qr,v);
     53     if(qr>mid)add(rt<<1|1,mid+1,r,ql,qr,v);
     54 }
     55 ll query(int rt,int l,int r,int pos)
     56 {
     57     ll ans=val[rt];
     58     int mid=(l+r)>>1;
     59     if(l==r)return ans;
     60     if(pos<=mid)ans=(ans+query(rt<<1,l,mid,pos))%mod;
     61     else ans=(ans+query(rt<<1|1,mid+1,r,pos))%mod;
     62     return ans;
     63 }
     64 int main()
     65 {
     66     scanf("%d%d",&n,&q);
     67     for(int x,y,i=1;i<n;++i)
     68     {
     69         scanf("%d%d",&x,&y);
     70         g[x].push_back(y);
     71         g[y].push_back(x); 
     72     }
     73     dfs(1,0);
     74     while(q--)
     75     {
     76         int opt,u,d;
     77         scanf("%d",&opt);
     78         if(opt==1)
     79         {
     80             scanf("%d%d",&u,&d);
     81             add(1,1,n,1,lpos[u]-1,1ll*sz[u]*inv(n,mod)%mod*d%mod);
     82             add(1,1,n,rpos[u]+1,n,1ll*sz[u]*inv(n,mod)%mod*d%mod);
     83             if(g[u].size()>B)addt[u]=(addt[u]+d)%mod;
     84             else
     85             {
     86                 for(int v:g[u])if(v!=f[u])
     87                 {
     88                     add(1,1,n,lpos[v],rpos[v],1ll*(n-sz[v])*inv(n,mod)%mod*d%mod);
     89                 }
     90                 add(1,1,n,lpos[u],lpos[u],d);
     91             }
     92         }
     93         else
     94         {
     95             scanf("%d",&u);
     96             ll ans=(addt[u]+query(1,1,n,lpos[u]))%mod; 
     97             while(top[u])
     98             {
     99                 u=top[u];
    100                 ans=(ans+1ll*(n-sz[u])*inv(n,mod)%mod*addt[f[u]]%mod)%mod;
    101                 u=f[u];
    102             }
    103             printf("%I64d
    ",ans);
    104         }
    105     }
    106 }
    View Code
  • 相关阅读:
    P1843 奶牛晒衣服
    P1577 切绳子
    P2777 [AHOI2016初中组]自行车比赛——洛谷
    选择我自己的算法 2012年CCC加拿大高中生信息学奥赛
    如何修改博客园里个人首页背景(form:cot 大犇)
    洛谷P1105 平台
    SPFA模板板板板板板板板板板板板板板板板板板板板板板板板板板板板板板板板板板板板板板板板板板板板板板
    洛谷p2504 HAOI2006 聪明的猴子
    舒适的路线
    超级质数
  • 原文地址:https://www.cnblogs.com/uuzlove/p/11896865.html
Copyright © 2020-2023  润新知