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 }
View Code

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 }
View Code

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 }
View Code

AK了好高兴,不过还是运气比较好的原因。jiry半小时AK实在不能再orz

posted @ 2014-10-04 23:26  ZYF-ZYF  Views(398)  Comments(0Edit  收藏  举报