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\n",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版本

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

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

猜你喜欢

转载自www.cnblogs.com/codeoosacm/p/11300002.html