codeforces round 315 div2 题解

来源:互联网 发布:怎么登录淘宝客 编辑:程序博客网 时间:2024/05/06 11:29

数学专场..

A : 推公式

#include <bits/stdc++.h>using namespace std;int t,s,q;int main(){cin>>t>>s>>q;int res = 0;while(s<t){int x = s*q;s = x;res++;}cout<<res<<endl;return 0;}

B: 考虑中间那个位置乱搞一下

#include <bits/stdc++.h>using namespace std;map<int, int> m;map<int, int> m2;int a[100010];int ans[100010];int main(){int n;cin>>n;for(int i=1; i<=n; i++){scanf("%d", &a[i]);m[a[i]]++;}int k=1;for(int i=1; i<=n; i++){if(m[a[i]] > 1||a[i] > n){m[a[i]] --;ans[i] = -1;}else ans[i] = a[i], m2[a[i]] = true;}for(int i=1; i<=n; i++){if(ans[i] == -1){while(k<=n&&m2[k])k++;ans[i] = k;m2[k] = true;}}for(int i=1; i<=n; i++)printf("%d ", ans[i]);return 0;}


C: 大暴力。。。
 #include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<vector>#include<set>#include<map>#include<queue>#include<math.h>using namespace std;#define maxn 2000020int flag[maxn],num[maxn];int pal[maxn];int gcd(int a,int b){if(b!=0) return gcd(b,a%b);else return a;}void getprime(){fill(num,num+1+maxn,1);num[0]=num[1]=0;int t=0;for(int i=2;i<=maxn;i++){if(num[i]){for(int j=2*i;j<=maxn;j+=i){num[j]=0;}}num[i]+=num[i-1];}}bool judge(int n){int t=0;while(n){pal[t++]=n%10;n=n/10;}for(int i=0;i<t/2;i++){if(pal[i]!=pal[t-1-i]) return false;}return true;}int main(){getprime();int m=0,c=0;int p,q;scanf("%d%d",&p,&q);int lmax=-1;for(int i=1;i<=maxn;i++){if(judge(i)&&i!=0) c++;if(q*num[i]<=p*c){lmax=i;}}if(lmax==-1) printf("Palindromic tree is better than splay tree\n");else printf("%d\n",lmax);}

D: 首先给出集合中的三种关系: 自反, 对称,传递, 两个集合等价的定义是同时具有自反对称和传递性。 这里求的是满足传递和对称性,但不是等价集合的集合个数。

首先,如果对于一个二元组 <x, y> 如果它满足传递和对称性的话 那么可以推出<x, y> == <y, x> -> <x, x> 也就是说x, y都满足自反性。 这样的话,我们就可以把这个集合的元素分成若干个块,每一个块内都是一个满足自反,传递, 对称的这么一个块, 那么我们只需要不让所有的元素都放在集合里面就可以了。

ok。。。 那么首先我们熟悉一下第二类斯特林数。 string[I][j] = string[I-1][j]*j + string[I-1][j-1];  这个是递推公式。 string[I][j]代表I个元素分成j个集合的划分方案。

那么对于每一个i来说的话, f[I] 就是I个元素所能分配的个数,且集合不为空。 f[I] = sum(string[I][k]) 1<=k<=I;

那么对于这道题答案就不是就是C(n,i)*f[I]+1  1<=I<=n-1;

#include<iostream>#include<fstream>#include<iomanip>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<iomanip>#include<algorithm>#include<list>#include<map>#include<set>#include<queue>#include<deque>#include<vector>#include<functional>#include<string>#define INF 1000000007#define pb push_back#define mp make_pair#define ll long long#define rep(i,k) for(int i=G.start[k];i!=INF;i=G.next[i])using namespace std;int n;long long st[4005][4005],f[4005];int C[4005][4005];void Stirling(){for(int i=0;i<4005;i++)st[i][0]=st[i][1]=1;for(int i=2;i<4005;i++)for(int j=2;j<=i;j++)st[i][j]=(st[i-1][j-1]+j*st[i-1][j])%INF;for(int i=0;i<4005;i++)for(int j=1;j<=i;j++)f[i]=(f[i]+st[i][j])%INF;}void C0(){for(int i=0;i<4005;i++)C[i][0]=C[i][i]=1;for(int i=1;i<4005;i++)for(int j=1;j<=i;j++)C[i][j]=(C[i-1][j-1]+C[i-1][j])%INF;}int main(){ios::sync_with_stdio(false);cin>>n;Stirling();f[0]=1;C0();long long ans=0;for(int i=1;i<=n-1;i++){ans=(ans+(C[n][i]*(ll)f[i])%INF)%INF;}ans++;cout<<ans<<endl;return 0;}

E: 2-sat判定  好题!!

看了一天还是不会做的2-sat。。。 这里膜拜一下sjut的toosimple牛。。 顺便膜拜一下代码:

#include <bits/stdc++.h>using namespace std;#define rep(i,a,n) for (int i=(a);i<=(n);i++)#define per(i,n,a) for (int i=n;i>=a;i--)#define pb push_back#define mp make_pair#define all(x) (x).begin(),(x).end()#define SZ(x) ((int)(x).size())#define fi first#define se secondtypedef vector<int> VI;typedef long long ll;typedef pair<int,int> PII;const ll mod=1000000007;ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}#define Fast_IO ios_base::sync_with_stdio(0);cin.tie(0)namespace SAT2 {const int N = 410;VI e[N];int top,Index,scc,Instack[N],Stack[N],DFN[N],Low[N];int Belong[N];void init(){rep(i, 0, N-1) e[i].clear();}void add_edge(int u, int v){e[u].pb(v);}void tarjan(int u){DFN[u] = Low[u] = ++Index;Instack[u] = true;Stack[top++] = u;int size = e[u].size();for(int i=0; i<size; i++) {int v = e[u][i];if(!DFN[v]){tarjan(v);Low[u] = min(Low[u], Low[v]);}else if(Instack[v]&&Low[u] > DFN[v])Low[u] = DFN[v];}if(Low[u] == DFN[u]){scc++;while(true){int tmp = Stack[--top];Instack[tmp] = false;Belong[tmp] = scc;if(tmp == u) break;}}}void solve(int n){scc = Index = top = 0;memset(DFN, 0, sizeof(DFN));for(int i=0; i<2*n; i++)if(!DFN[i]) tarjan(i);}}int l;int n,m;char str[400];char s[100100];PII e[201000];char ret[500];int wc, wv;bool check(int d){SAT2::init();for(int i =0; i<m; i++){SAT2::add_edge(e[i].first, e[i].second);SAT2::add_edge(e[i].second^1, e[i].first^1);}for(int i=0; i<=d; i++){if(str[ret[i] - 'a'] == 'V') SAT2::add_edge(2*i+1, 2*i);else SAT2::add_edge(2*i, 2*i+1);}for(int i=0; i<n; i++){if(wc) SAT2::add_edge(2*i, 2*i+1);if(wv) SAT2::add_edge(2*i+1, 2*i);}SAT2::solve(n);for(int i=0; i<n; i++)if(SAT2::Belong[2*i] == SAT2::Belong[2*i+1])return false;return true;}void dfs(int d, int f){if(d == n) {puts(ret);throw 0;}int v = 0, c= 0;rep(i, (f?0:s[d]-'a'), l-1){ret[d] = i+'a';if(str[i] == 'V'){if(v >= 2) continue;v++;}else {if(c >= 2) continue;c++;}if(check(d)){dfs(d+1, f|(i!=s[d]-'a'));}}}int main(){ wc = 1;wv = 1;scanf("%s", str);l = strlen(str);rep(i, 0, l-1) wc &= (str[i] == 'C'), wv&=(str[i] =='V');cin>>n>>m;rep(i, 0, m-1){int t1,t2;char c1[3], c2[3];scanf("%d %s %d %s", &t1, c1, &t2, c2);t1--; t2--;t1 = c1[0] == 'V'?2*t1:2*t1+1;t2 = c2[0] == 'V'?2*t2:2*t2+1;e[i] = mp(t1, t2);}scanf("%s", s);try{dfs(0, 0);}catch(int e){return 0;}puts("-1");return 0;}


0 0
原创粉丝点击