2019牛客国庆集训派对day5
A Simple Arithmetic
题目链接
题意:求向下取整的 a/b
思路:精度问题python莽过
还可以c++和long double计算
try: while True: s = input() a,b=map(int,s.split()) print(a//b) except EOFError: pass
D Dynamic Graph
题目链接
题意:给你有向无环图,一种操作对于一个点进行翻转,求点对能到达的。
思路:topo+搜索,用bitset存关系,复杂度n^2
#include <bits/stdc++.h> #define maxn 305 using namespace std; int deg[maxn]; vector <int>g[maxn]; int color[maxn]; int vis[maxn]; bitset<maxn>p[maxn]; void dfs(int x){ if(vis[x])return; vis[x]=1; p[x].reset(); for(int i=0;i<g[x].size();i++){ int v=g[x][i]; dfs(v); if(!color[x]&&!color[v]){ p[x]|=p[v]; p[x][v]=1; } } } int main(){ int n,m,q; while(scanf("%d%d%d",&n,&m,&q)!=EOF){ for(int i=1;i<=n;i++){ g[i].clear(); deg[i]=color[i]=0; } int u,v; for(int i=0;i<m;i++){ scanf("%d%d",&u,&v); g[u].push_back(v); deg[v]++; } while(q--){ int x; scanf("%d",&x); color[x]^=1; memset(vis,0,sizeof vis); for(int i=1;i<=n;i++) if(deg[i]==0) dfs(i); int ans=0; for(int i=1;i<=n;i++) ans+=p[i].count(); printf("%d\n",ans); } } }
E Longest Increasing Subsequence
题目链接
题意:定义Bi是原序列A删除第i个元素的序列,定义LIS是原LIS的f[i]数组的异或和。求每个Bi的LIS。
思路:先n^2跑出LIS中的F[i]和建边。枚举每个点topo进行O(n)的跑 总时间复杂度n^2
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll maxn = 1e5 + 5; const ll mod = 1e9 + 7; int a[maxn]; int f[maxn]; int t[maxn]; int indeg[maxn]; int deg[maxn]; int n; vector <int>G[maxn]; void get_LIS(){ int i,j; for(i=1;i<=n;i++){ f[i]=1; for(j=1;j<=i-1;j++){ if(a[j]<a[i]) { if(f[j]+1>f[i]){ f[i]=f[j]+1; } } } } for(i=1;i<=n;i++){ for(j=1;j<=i-1;j++){ if(f[j] + 1 == f[i]&&a[i] > a[j]){ G[j].push_back(i); indeg[i]++; // cout<<j<<" "<<i<<endl; } } } } void topo(int x){ queue <int>q; q.push(x); while(!q.empty()){ int f=q.front(); q.pop(); for(int i=0;i<G[f].size();i++){ int v=G[f][i]; deg[v]--; if(deg[v]==0){ q.push(v); t[v]--; } } } } int main() { while(scanf("%d", &n)!=EOF){ int i,j; for (i = 1; i <= n; i++) { scanf("%d", &a[i]); G[i].clear(); } memset(indeg,0,sizeof indeg); get_LIS(); for(i=1;i<=n;i++){ for(j=1;j<=n;j++){ t[j]=f[j]; deg[j]=indeg[j]; } topo(i); // for(int j=1;j<=n;j++){ // if(j==i)continue; // printf("%d ",t[j]); // } // printf("\n"); int ans; int flag=0; for(int j=1;j<=n;j++){ if(j==i)continue; if(!flag) { ans=t[j]*t[j]; flag=1; }else ans=ans^(t[j]*t[j]); } printf("%d%c",ans,i==n?'\n':' '); } } }
F Simple Algebra
题目链接
题意:求满足对于任意x,y使得的a,b,c
思路:对于a和c任意一个大于0,可以转换为4ac-b*b>=0。若a和c任意一个小于0,都可以找出反例,即无解。当a=0且c=0时,只有b=0特判即可。
#include <bits/stdc++.h> using namespace std; int a,b,c; void solve(){ if((a>0||c>0)) { if(4*a*c-b*b>=0) puts("Yes"); else puts("No"); }else if(a<0||c<0){ puts("No"); }else{ if(b==0) puts("Yes"); else puts("No"); } } int main(){ while(scanf("%d%d%d",&a,&b,&c)!=EOF){ solve(); } }
G 2017
题目链接
题意:给出a,b,c,d。求a<x<b并且c<y<d中x*y为2017倍数的个数
思路:当一个数为2017倍数,另一个为任意值都可。容斥。
#include<iostream> #include<cstdio> #include<cstring> #include<map> #include<vector> #include<set> #include<queue> #include<algorithm> #include<string> #include<cmath> #include<stack> #include<functional> #include<bitset> #define ll long long #define maxn 100002 const int INF = 0x3f3f3f3f; using namespace std; int main(void){ ll a, b, c, d, e, f; while(scanf("%lld %lld %lld %lld",&a,&b,&c,&d)!=EOF){ e = (b / 2017 * 2017 - (a - 1) / 2017 * 2017) / 2017; f = (d / 2017 * 2017 - (c - 1) / 2017 * 2017) / 2017; printf("%lld\n",e * (d - c + 1) - e * f + f * (b - a + 1)); } return 0; }
K 2017 Revenge
题目链接
题意:给出n个数,选若干个满足乘积mod2017=r。问多少种方案。
思路:bitset优化dp,待补
L Nice Trick
题目链接
题意:给出三元式和计算方法,求四元式的计算值。
思路:模出样例,前缀和处理。
#include<bits/stdc++.h> using namespace std; using ll = long long; const ll maxn = 1e5 + 5; const ll mod = 1e9 + 7; ll a[maxn]; ll s1[maxn]; ll s2[maxn]; ll s3[maxn]; ll S[maxn]; ll qpow(ll A, ll B) { ll t = 1; while (B) { if ((B & 1)) { t = t * A%mod; } A = A * A%mod; B = B >> 1; } return t; } int main() { ll n; while (~scanf("%lld", &n)) { for (ll i = 1; i <= n; i++) { scanf("%lld", &a[i]); s1[i] = (s1[i - 1] + a[i]) % mod; s2[i] = (s2[i - 1] + a[i] * a[i] % mod) % mod; s3[i] = (s3[i - 1] + a[i] * a[i] % mod* a[i] % mod) % mod; //cout << s1[i] << " " << s2[i] << " " << s3[i] << endl; S[i] = (s1[i] * s1[i] % mod * s1[i] % mod - 3 * s2[i] % mod * s1[i] % mod + mod + 2 * s3[i] % mod) % mod*qpow(6, mod - 2) % mod; //cout << i << " " << S[i] << endl; } ll ans = 0; for (int l = 3; l <= n; l++) { ans = (ans + a[l] * S[l - 1] % mod) % mod; } cout << ans << endl; } }