CH Round #55 - Streaming #6 (NOIP模拟赛day2)
A.九九归一
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2355%20-%20Streaming%20%236%20(NOIP模拟赛day2)/九九归一
题解:题目意思就是问 a是不是n的一个原根
首先如果 gcd(a,n)!=1 显然不可能 输出0
然后我们有性质
若 gcd(a,n)==1 则 a模n的阶k|phi(n)
所以就可以枚举phi(n)的约数判定了
复杂度题解中说是 q*logn*logn*logn的。。。
代码:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #include<iostream> 7 #include<vector> 8 #include<map> 9 #include<set> 10 #include<queue> 11 #include<string> 12 #define inf 1000000000 13 #define maxn 100000 14 #define maxm 500+100 15 #define eps 1e-10 16 #define ll long long 17 #define pa pair<int,int> 18 #define for0(i,n) for(int i=0;i<=(n);i++) 19 #define for1(i,n) for(int i=1;i<=(n);i++) 20 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 21 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 22 using namespace std; 23 inline int read() 24 { 25 int x=0,f=1;char ch=getchar(); 26 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 27 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 28 return x*f; 29 } 30 int n,tot,a[maxn]; 31 int power(int xx,int yy) 32 { 33 ll t=1,x=xx,y=yy; 34 for(;y;y>>=1,x=(x*x)%n) 35 if(y&1)t=(t*x)%n; 36 return t; 37 } 38 inline bool check(int m) 39 { 40 for1(i,tot)if(power(m,a[i])==1)return 0; 41 return 1; 42 } 43 inline int gcd(int x,int y){return y?gcd(y,x%y):x;} 44 int main() 45 { 46 freopen("input.txt","r",stdin); 47 freopen("output.txt","w",stdout); 48 n=read(); 49 int x=n,y=n; 50 for2(i,2,sqrt(n)) 51 if(x%i==0) 52 { 53 y=(y/i)*(i-1); 54 while(x%i==0)x/=i; 55 } 56 if(x!=1)y=(y/x)*(x-1); 57 for1(i,y)if(y%i==0)a[++tot]=i;tot--; 58 int cs=read(); 59 while(cs--) 60 { 61 int m=read(); 62 if(gcd(m,n)!=1)printf("0"); 63 else if(check(m))printf("1"); 64 else printf("0"); 65 } 66 printf("\n"); 67 return 0; 68 }
B.LCA的统计
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2355%20-%20Streaming%20%236%20(NOIP模拟赛day2)/LCA的统计
题解:首先枚举是一定要的,我们枚举 lca(i,j)然后看一下什么样的i,j是我们枚举的这个值。
稍微想想会发现f[x]=w[x]*((s[x]*s[x])-sigma(s[y]*s[y])) y是x 的子树
然后防止爆long long 就行了
代码:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #include<iostream> 7 #include<vector> 8 #include<map> 9 #include<set> 10 #include<queue> 11 #include<string> 12 #define inf 1000000000 13 #define maxn 1500000 14 #define maxm 500+100 15 #define eps 1e-10 16 #define ll long long 17 #define pa pair<int,int> 18 #define for0(i,n) for(int i=0;i<=(n);i++) 19 #define for1(i,n) for(int i=1;i<=(n);i++) 20 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 21 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 22 #define mod 1000000007 23 using namespace std; 24 inline int read() 25 { 26 int x=0,f=1;char ch=getchar(); 27 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 28 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 29 return x*f; 30 } 31 struct edga{int go,next;}e[maxn]; 32 int n,tot,head[maxn]; 33 ll s[maxn],f[maxn],w[maxn]; 34 inline void insert(int x,int y) 35 { 36 e[++tot].go=y;e[tot].next=head[x];head[x]=tot; 37 } 38 void dfs(int x) 39 { 40 f[x]=0;s[x]=w[x]; 41 for(int i=head[x],y;i;i=e[i].next) 42 { 43 dfs(y=e[i].go); 44 f[x]=((f[x]-w[x]*(s[y]*s[y]%mod))%mod+mod)%mod; 45 s[x]=(s[x]+s[y])%mod; 46 } 47 f[x]=(f[x]+w[x]*(s[x]*s[x]%mod))%mod; 48 } 49 int main() 50 { 51 freopen("input.txt","r",stdin); 52 freopen("output.txt","w",stdout); 53 n=read();w[1]=read()%mod; 54 for2(i,2,n)insert(read(),i),w[i]=read()%mod; 55 dfs(1); 56 ll ans=0; 57 for1(i,n)ans=(ans+f[i])%mod; 58 printf("%lld\n",ans); 59 return 0; 60 }
C.四驱兄弟
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2355%20-%20Streaming%20%236%20(NOIP模拟赛day2)/四驱兄弟
题解:猜想大概是MST,然后发现不会证,就打了弃疗了。结果A了。。。
出题人是这样说的:
考虑图连通的情况,那么假设最小生成树不是第k小边最小生成树,就可以把两个树各取一点变成一个更小的生成树,就矛盾了
没想到我用map+cin居然没T
代码:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #include<iostream> 7 #include<vector> 8 #include<map> 9 #include<set> 10 #include<queue> 11 #include<string> 12 #define inf 1100000000 13 #define maxn 200000+1000 14 #define maxm 500+100 15 #define eps 1e-10 16 #define ll long long 17 #define pa pair<int,int> 18 #define for0(i,n) for(int i=0;i<=(n);i++) 19 #define for1(i,n) for(int i=1;i<=(n);i++) 20 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 21 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 22 #define mod 1000000007 23 using namespace std; 24 typedef map<string,int>::const_iterator cit; 25 typedef map<string,int>::value_type vt; 26 inline int read() 27 { 28 int x=0,f=1;char ch=getchar(); 29 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 30 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 31 return x*f; 32 } 33 map<string,int>mp; 34 struct rec{int u,v,w;}e[maxn]; 35 int n,m,tot,a[maxn],fa[maxn]; 36 string s; 37 inline bool cmp(rec a,rec b) 38 { 39 return a.w<b.w; 40 } 41 inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} 42 int main() 43 { 44 freopen("input.txt","r",stdin); 45 freopen("output.txt","w",stdout); 46 n=read();m=read(); 47 for1(i,m) 48 { 49 e[i].w=read(); 50 cin>>s; 51 cit j=mp.find(s); 52 if(j!=mp.end())e[i].u=j->second; 53 else 54 { 55 mp.insert(mp.begin(),vt(s,++tot)); 56 e[i].u=tot; 57 } 58 cin>>s; 59 j=mp.find(s); 60 if(j!=mp.end())e[i].v=j->second; 61 else 62 { 63 mp.insert(mp.begin(),vt(s,++tot)); 64 e[i].v=tot; 65 } 66 } 67 sort(e+1,e+m+1,cmp); 68 for1(i,tot)fa[i]=i; 69 int j=1; 70 for1(i,n) 71 { 72 while(j<=m&&find(e[j].u)==find(e[j].v))j++; 73 if(j>m)a[i]=inf; 74 else 75 { 76 a[i]=e[j].w; 77 fa[find(e[j].u)]=find(e[j].v); 78 } 79 j++; 80 } 81 for1(i,n) 82 if(a[i]==inf)printf("INF\n");else printf("%d\n",a[i]); 83 return 0; 84 }
AK了好高兴,不过还是运气比较好的原因。jiry半小时AK实在不能再orz