zoukankan      html  css  js  c++  java
  • 2019 Wannafly summer camp Day2

    Day2 还是很有难度的emmmm

    A - Por Costel and Azerah

    给定n个数,从其中取出若干个数使其和为偶数,问有多少种取法

    (1)dp做法:挖坑待更

    (2)数学做法:可以分为三种情况:

            1,从奇数中取2*x个 s1=C(n,2)+C(n,4)+...+C(n,n/2*2)

            2,从偶数中取任意个s2=C(n,1)+C(n,2)+C(n,3)+...+C(n,n)

            3,从奇数中取2*x个,偶数中取任意个s3=s1*s2

            用组合数可以算出来

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int odd,even;
     4 const int mod=1e9+7;
     5 int power(int a,int n)
     6 {
     7     int ans=1,tmp=a;
     8     while(n)
     9     {
    10         //cout<<ans<<endl;
    11         if(n&1) ans=1ll*ans*tmp%mod;
    12         tmp=1ll*tmp*tmp%mod;
    13         n/=2;
    14     }
    15     return ans;
    16 }
    17 int main()
    18 {
    19     freopen("azerah.in","r",stdin);
    20     freopen("azerah.out","w",stdout);
    21     ios::sync_with_stdio(0);
    22     int n,t;cin>>t;
    23     while(t--){
    24         even=odd=0;
    25     cin>>n;
    26     for(int i=1;i<=n;++i)
    27     {
    28         int t;cin>>t;
    29         if(t&1) ++odd;
    30         else ++even;
    31     }
    32     int s1=power(2,odd-1)-1,s2=power(2,even)-1;
    33     if(odd==0) s1=0;if(even==0) s2=0;
    34     long long ans=(s1+s2+1ll*s1*s2)%mod;
    35     cout<<ans<<endl;
    36     }
    37 }
    View Code

    B - Por Costel and the Algorithm

    参考https://www.cnblogs.com/autsky-jadek/p/6338115.html

    给一个有向图,求它的最短路树,先输出最短路树的边,再输出其他边

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define pil pair<int,ll>
     4 #define mem(a) memset(a,0,sizeof(a))
     5 using namespace std;
     6 const int maxn=2e5+5;
     7 ll dis[maxn];
     8 int fir[maxn],pre[maxn],n,m,cnt;
     9 bool vis[maxn],used[maxn*2];
    10 struct edge { int to,v,nex;}E[maxn*2];
    11 struct cmp { bool operator()(pil a,pil b){return a.second>b.second;}};
    12 void add(int fro,int to,int v){E[++cnt].to=to,E[cnt].v=v,E[cnt].nex=fir[fro],fir[fro]=cnt;}
    13 void ini(){mem(fir),mem(pre),mem(vis),mem(E),mem(used);fill(dis,dis+maxn,1e18);cnt=0;}
    14 void dfs(int now)
    15 {
    16     for(int i=fir[now];i;i=E[i].nex)
    17     {
    18         if(used[i])
    19         {
    20             cout<<i<<" ";
    21             dfs(E[i].to);
    22         }
    23     }
    24 }
    25 void dij()
    26 {
    27     priority_queue<pil,vector<pil>,cmp>pq;
    28     pq.push({1,0});
    29     dis[1]=0;
    30     while(!pq.empty())
    31     {
    32         int now=pq.top().first;
    33         pq.pop();
    34         if(vis[now]) continue;
    35         vis[now]=1;
    36         for(int i=fir[now];i;i=E[i].nex)
    37         {
    38             int to=E[i].to,
    39                 v=E[i].v;
    40             if(vis[to]==0 && dis[to]>dis[now]+v)
    41             {
    42                 //cout<<"test:"<<endl;
    43                 //printf("i: %d now: %d to:%d used: %d pre: %d
    ",i,now,to,used[pre[to]],pre[to]);
    44                 dis[to]=dis[now]+v;
    45                 used[pre[to]]=0;
    46                 used[i]=1;
    47                 pre[to]=i;
    48                 pq.push({to,dis[to]});
    49             }
    50         }
    51     }
    52 }
    53 int main()
    54 {
    55     freopen("algoritm.in","r",stdin);
    56     freopen("algoritm.out","w",stdout);
    57     ios::sync_with_stdio(0);
    58     int t;cin>>t;
    59     while(t--)
    60     {
    61         ini();
    62         cin>>n>>m;
    63         for(int i=1;i<=m;++i)
    64         {
    65             int a,b,c; cin>>a>>b>>c;
    66             add(a,b,c);
    67         }
    68         dij();
    69         dfs(1);
    70         for(int i=1;i<=m;++i) if(!used[i]) cout<<i<<" "; 
    71         cout<<endl;
    72     }
    73 }
    前向星版本
     1 #include <bits/stdc++.h>
     2 #define ll long long
     3 #define mem(a) memset(a,0,sizeof(a))
     4 using namespace std;
     5 const int maxn=1e5+5;
     6 struct pii{int to,v,id;};
     7 struct pil{int first;ll second;};
     8 struct cmp{bool operator()(pil a,pil b){return a.second>b.second;}};
     9 vector<pii>G[maxn];
    10 int pre[maxn],n,m;
    11 ll dis[maxn];
    12 bool vis[maxn],used[maxn*2];
    13 void ini() { mem(pre),mem(vis),mem(used);for(int i=0;i<maxn;++i)G[i].clear();fill(dis,dis+maxn,1e18);}
    14 void dij()
    15 {
    16     priority_queue<pil,vector<pil>,cmp>pq;
    17     pq.push({1,0});
    18     dis[1]=0;
    19     while(!pq.empty())
    20     {
    21         int now=pq.top().first;
    22         pq.pop();
    23         if(vis[now]) continue;vis[now]=1;
    24         for(auto t:G[now])
    25         {
    26             int to=t.to,v=t.v,id=t.id;
    27             if(!vis[to] && dis[to]>dis[now]+v)
    28             {
    29                 dis[to]=dis[now]+v;
    30                 pq.push({to,dis[to]});
    31                 used[pre[to]]=0;
    32                 pre[to]=id;
    33                 used[id]=1;
    34             }
    35         }
    36     }
    37 }
    38 void dfs(int now)
    39 {
    40     for(auto t:G[now])
    41     {
    42         int to=t.to;
    43         if(used[t.id])
    44         {
    45             cout<<t.id<<" ";
    46             dfs(to);
    47         }
    48     }
    49 }
    50 int main()
    51 {
    52     freopen("algoritm.in","r",stdin);
    53     freopen("algoritm.out","w",stdout);
    54     ios::sync_with_stdio(0);
    55     int t;cin>>t;
    56     while(t--) {
    57         ini();
    58         cin >> n >> m;
    59         for (int i = 1; i <= m; ++i) {
    60             int a, b, c;
    61             cin >> a >> b >> c;
    62             G[a].push_back({b, c, i});
    63         }
    64         dij();
    65         dfs(1);
    66         for(int i=1;i<=m;++i) if(used[i]==0) cout<<i<<" ";cout<<endl;
    67     }
    68 }
    vector版本

    F - Por Costel and the Alien Invasion

     题意:每个线段有一个权值(高度),有以下操作:

      (1)加入一条线段

      (2)删除最近加入的一条线段

      (3)给一个坐标(线段上的点),查询这个点对应的最低线段的权值

      RMQ,对于每个区间维护一个vector,对于后来的线段,如果位置比原本的低,更新,否则再加上一个当前的区间高度即可。删除直接pop_back。

      

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=3e5+5;
     4 const int inf=1e9+9;
     5 vector<int>tree[maxn<<2];
     6 #define pii pair<int,int>
     7 void insert(int nl,int nr,int root,int l,int r,int v)
     8 {
     9     //cout<<"QAQ";
    10     if (l >= nl && r <= nr) {
    11         int back = tree[root].empty()?inf:tree[root].back();
    12         tree[root].push_back(v < back ? v : back);
    13         return;
    14     }
    15     int mid=(l+r)/2;
    16     if (nl <= mid) insert(nl, nr, root*2, l, mid, v);
    17     if (nr > mid) insert(nl, nr, root*2+1, mid + 1, r, v);
    18 }
    19 void del(int nl,int nr,int root,int l,int r)
    20 {
    21     if(nl<=l && r<=nr)
    22     {
    23         tree[root].pop_back();
    24         return;
    25     }
    26     int mid=(l+r)/2;
    27     if(nl<=mid) del(nl,nr,root*2,l,mid);
    28     if(nr>mid) del(nl,nr,root*2+1,mid+1,r);
    29 }
    30 int query(int pos,int root,int l,int r)
    31 {
    32     if(l==r)
    33     {
    34         if(tree[root].size()==0) return inf;
    35         else return tree[root].back();
    36     }
    37     int mid=(l+r)/2;
    38     int ans;
    39     if(tree[root].size()==0) ans=inf;
    40     else ans=tree[root].back();
    41     if(pos<=mid) return min(ans,query(pos,root*2,l,mid));
    42     else return min(ans,query(pos,root*2+1,mid+1,r));
    43 }
    44 int main()
    45 {
    46     freopen("invazia.in","r",stdin);
    47     freopen("invazia.out","w",stdout);
    48     int n,m;vector<pii>pla;
    49     scanf("%d%d",&n,&m);
    50     for(int i=1;i<=m;++i)
    51     {
    52         char t;scanf(" %c",&t);
    53         if(t=='I')
    54         {
    55             int a,b,c;scanf("%d%d%d",&a,&b,&c);
    56             pla.push_back({a,b});
    57             insert(a,b,1,1,n,c);
    58         }
    59         else if(t=='E'){
    60             del(pla.back().first,pla.back().second,1,1,n);
    61             pla.pop_back();
    62         } else {
    63             int pos;scanf("%d",&pos);
    64             int ans=query(pos,1,1,n);
    65             if(ans==inf) puts("GUITZZZ!");
    66             else printf("%d
    ",ans);
    67         }
    68     }
    69 }
    View Code

    H - Por Costel and the Match

    分类并查集,参考poj食物链

    还有一个做法是带权并查集不过先占个坑

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=2e5+5;
     4 int fa[maxn];
     5 int fin(int x){return x==fa[x]?x:fa[x]=fin(fa[x]);}
     6 
     7 int main()
     8 {
     9     freopen("meciul.in","r",stdin);
    10     freopen("meciul.out","w",stdout);
    11     int t;scanf("%d",&t);
    12 while(t--)
    13 {
    14     int n,m;
    15     scanf("%d%d",&n,&m);
    16     for(int i=1;i<maxn;++i) fa[i]=i;
    17     for(int i=1;i<=m;++i)
    18     {
    19         int a,b;
    20         scanf("%d%d",&a,&b);
    21         int x=fin(a),y=fin(b),c=fin(a+n);
    22         if(x==y) puts("NO");
    23         else{
    24             puts("YES");
    25             a=fin(a+n),b=fin(b+n);
    26             fa[y]=a;
    27             fa[x]=b;
    28         }
    29     }
    30 }
    31 }
    View Code

    I - Por Costel and the Pairs

    数形结合一下?画个y=k/x的图像,用面积搞一下

    (牛逼网友说可以分块打表emmm)

     1 #include<bits/stdc++.h>
     2 #define int long long
     3 using namespace std;
     4 
     5 signed main()
     6 {
     7     freopen("perechi3.in","r",stdin);
     8     freopen("perechi3.out","w",stdout);
     9     ios::sync_with_stdio(0);
    10     int t;cin>>t;
    11     while (t--)
    12     {
    13         int n;cin>>n;
    14         int i;
    15         int ans=0;
    16         for(i=1;i*i<=n;++i)
    17         {
    18             ans+=n/i;
    19         }
    20         ans=ans*2-(--i)*i;
    21         cout<<ans<<endl;
    22     }
    23 }
    View Code

    K - Por Costel and the Firecracker

    根据mod,可知要求的数下标在1e7级别,不过限制了内存,所以可以分块打表,先隔1000个打表一次,可以得到一个1e4的表,对于每次询问,可以在1000次之内得到结果

    (也可以隔100个打表一次,合理即可)注意下标要从0开始

    这是隔100的

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=1e5+5;
     4 const int mod=1e7+3;
     5 int pos[maxn];
     6 int main()
     7 {
     8     freopen("pocnitoare.in","r",stdin);
     9     freopen("pocnitoare.out","w",stdout);
    10     ios::sync_with_stdio(0);
    11     int n,a,b,x,q,q1;
    12 
    13     int ans=0;
    14     cin>>n>>a>>b>>x>>q>>q1;
    15     int xx=x;
    16     pos[0]=x-a;
    17     for(int i=1;i<=10000000;++i)
    18     {
    19         if(i%100==0)
    20         {
    21             pos[i/100]=x;
    22         }
    23         if(i==q1) ans=x;
    24         x=(1ll*i*x+a)%n;
    25     }
    26     cout<<ans<<endl;
    27     int tmp=ans;
    28     for(int i=2;i<=q;++i)
    29     {
    30         int qnow=((1ll*tmp*(i-1)+b)+1)%mod;
    31         int start=qnow/100;
    32         tmp=pos[start];
    33         for(int j=start*100;j<qnow;++j)
    34         {
    35             tmp=(1ll*j*tmp+a)%n;
    36             if(j==0) tmp=xx;
    37         }
    38         cout<<tmp<<endl;
    39     }
    40 }
    View Code

    L - Por Costel and the Semipalindromes

    定义半回文串是一定长度的前缀和后缀相等的字符串,给定n和k,求一个长度为n的字典序第k小的半回文串

    前缀/后缀长度取1即可

    把k分解为长度为n-1的01串即可,并使s[n]=s[1]

     1 #include<bits/stdc++.h>
     2 #define int long long
     3 using namespace std;
     4 int n,k;
     5 vector<int> div(int nn)
     6 {
     7     vector<int>v;
     8     while(nn)
     9     {
    10         v.push_back(nn&1);
    11         nn/=2;
    12     }
    13     while (v.size()<n-1)
    14     {
    15         v.push_back(0);
    16     }
    17     reverse(v.begin(),v.end());
    18     return v;
    19 }
    20 signed main()
    21 {
    22     freopen("semipal.in","r",stdin);
    23     freopen("semipal.out","w",stdout);
    24     ios::sync_with_stdio(0);
    25     int t;cin>>t;
    26     while(t--)
    27     {   
    28         cin>>n>>k;
    29         vector<int>v;
    30         v=div(k-1);
    31         v.push_back(v[0]);
    32         for(int i:v)cout<<(i?'b':'a');
    33         cout<<endl;
    34     }
    35 }
    View Code

    睡了,待更。。。(咕了,以后没了)

    UPD:8.16,补F。

  • 相关阅读:
    多个在线参考手册,值得收藏
    DIV层,点“+”展开,“-”关闭
    网页设计标准尺寸
    【转】 大年三十整理的asp.net资料! (.NET) (ASP.NET)
    【转】xml操作
    【配色】web2.0 配色参考
    【转】关闭开机硬盘自检的方法
    【转】css的一些基础的东西
    web.config加密解密
    [转]用 Javascript 获取滚动条位置等信息
  • 原文地址:https://www.cnblogs.com/codeoosacm/p/11300002.html
Copyright © 2011-2022 走看看