ACM-ICPC 2018 沈阳赛区网络预赛 做题记录

考场上kdtree没调出来,回去立马发现了bug QAQ

真·自闭 嘤嘤嘤

补题进度:4/11

D.

求k短路,A*即可,用可持久化堆维护,O((K+N)*logN)

随便找份A*的板子改改就能A了

代码不贴了,要看的自己去找k短路

G.

容易发现a[n]=n^2+n

然后我们对m分解质因数,质因数不超过10个,然后我们容斥算一下就行了

扫描二维码关注公众号,回复: 3101849 查看本文章
 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define maxn 10005
 4 using namespace std;
 5 const ll mod=1000000007;
 6 int n,m;
 7 int pr[maxn],cnt;
 8 ll fastpow(ll a,ll p)
 9 {
10     ll ans=1;
11     while(p)
12     {
13         if(p&1)ans=ans*a%mod;
14         a=a*a%mod;p>>=1;
15     }
16     return ans;
17 }
18 int main()
19 {
20     ll inv2=fastpow(2,mod-2);
21     ll inv6=fastpow(6,mod-2);
22     while(~scanf("%d%d",&n,&m))
23     {
24         cnt=0;
25         for(int i=2;i*i<=m;++i)if(m%i==0)
26         {
27             pr[cnt++]=i;
28             while(m&&(m%i==0))m/=i;
29         }
30         if(m>1)pr[cnt++]=m;
31         int fullset=(1<<cnt)-1;
32         ll ans=0;
33         for(int S=0;S<=fullset;++S)
34         {
35             ll t=1,num=0;
36             for(int i=0;i<cnt;++i)if(S&(1<<i))num++,t*=pr[i];
37             ll k=n/t;
38             ll res=t*t%mod*k%mod*(k+1)%mod*(2*k+1)%mod*inv6%mod+t*k%mod*(k+1)%mod*inv2%mod;
39             res%=mod;
40             if(num&1)ans-=res;
41             else ans+=res;
42             ans=(ans%mod+mod)%mod;
43         }
44         printf("%d\n",(int)ans);
45     }
46     return 0;
47 } 

J.

以dfs序为x坐标,深度为y坐标建立kdtree

然后就变为范围修改范围查询了

上kdtree板子

  1 #include<bits/stdc++.h>
  2 #define inf 1000000000
  3 #define ll long long
  4 #define maxn 100005
  5 using namespace std;
  6 int now;
  7 struct point
  8 {
  9     int d[2],minv[2],maxv[2],l,r;
 10     ll v,sumv,addv,size;
 11     void clear(){d[0]=d[1]=minv[0]=minv[1]=maxv[0]=maxv[1]=l=r=v=sumv=0;}
 12 };
 13 bool operator ==(point a,point b){return a.d[0]==b.d[0]&&a.d[1]==b.d[1];}
 14 bool operator <(point a,point b){return a.d[now]<b.d[now];}
 15 int rt,cnt;
 16 point t[100005],a[100005],p;
 17 bool in(point a,point b)
 18 {
 19     return a.minv[0]<=b.minv[0]&&b.maxv[0]<=a.maxv[0]&&a.minv[1]<=b.minv[1]&&b.maxv[1]<=a.maxv[1];
 20 }
 21 bool out(point a,point b)
 22 {
 23     return a.maxv[0]<b.minv[0]||a.minv[0]>b.maxv[0]||a.maxv[1]<b.minv[1]||a.minv[1]>b.maxv[1];
 24 }
 25 void pushdown(int x)
 26 {
 27     int l=t[x].l,r=t[x].r;
 28     if(t[x].addv)
 29     {
 30         ll tag=t[x].addv;
 31         t[l].sumv+=t[l].size*tag;t[r].sumv+=t[r].size*tag;
 32         t[l].addv+=tag;t[r].addv+=tag;
 33         t[l].v+=tag;t[r].v+=tag;
 34         t[x].addv=0; 
 35     } 
 36 }
 37 void pushup(int x)
 38 {
 39     int l=t[x].l,r=t[x].r;
 40     t[x].size=t[l].size+t[r].size+1; 
 41     t[x].sumv=t[l].sumv+t[r].sumv+t[x].v;
 42     for(int i=0;i<2;i++)
 43     {
 44         t[x].minv[i]=t[x].maxv[i]=t[x].d[i];
 45         if(l)t[x].minv[i]=min(t[x].minv[i],t[l].minv[i]),t[x].maxv[i]=max(t[x].maxv[i],t[l].maxv[i]);
 46         if(r)t[x].minv[i]=min(t[x].minv[i],t[r].minv[i]),t[x].maxv[i]=max(t[x].maxv[i],t[r].maxv[i]);
 47     }
 48 }
 49 point tmp;
 50 void add(int x,ll v)
 51 {
 52     if(!x)return;
 53     pushdown(x);
 54     if(in(p,t[x]))
 55     {
 56         t[x].sumv+=v*t[x].size;
 57         t[x].v+=v;
 58         t[x].addv+=v;
 59         return;
 60     }
 61     if(out(p,t[x]))return;
 62     tmp.clear(); 
 63     tmp.minv[0]=tmp.maxv[0]=t[x].d[0];
 64     tmp.minv[1]=tmp.maxv[1]=t[x].d[1];
 65     if(in(p,tmp))t[x].v+=v;
 66     add(t[x].l,v);add(t[x].r,v);
 67     pushup(x);
 68 }
 69 ll query(int x)
 70 {
 71     ll ans=0;if(!x)return 0;
 72     pushdown(x);
 73     if(in(p,t[x]))return t[x].sumv;
 74     if(out(p,t[x]))return 0;
 75     tmp.clear();
 76     tmp.minv[0]=tmp.maxv[0]=t[x].d[0];
 77     tmp.minv[1]=tmp.maxv[1]=t[x].d[1];
 78     if(in(p,tmp))ans+=t[x].v;
 79     ans+=query(t[x].l)+query(t[x].r);
 80     pushup(x);
 81     return ans;
 82 }
 83 int rebuild(int l,int r,bool f)
 84 {
 85     if(l>r)return 0;
 86     int mid=(l+r)/2;now=f;
 87     nth_element(a+l,a+mid,a+r+1);
 88     t[mid]=a[mid];
 89     t[mid].l=rebuild(l,mid-1,f^1);
 90     t[mid].r=rebuild(mid+1,r,f^1);
 91     pushup(mid);
 92     return mid;
 93 }
 94 void read(int &x)
 95 {
 96     x=0;char ch=getchar();while(ch<'0'||ch>'9')ch=getchar();
 97     while('0'<=ch&&ch<='9')x=x*10+ch-'0',ch=getchar();
 98 }
 99 int n,q,opt,ans;
100 struct edge
101 {
102     int to,next;
103 }e[200005];
104 int head[100005],P;
105 void addedge(int u,int v)
106 {
107     e[++P].to=v;e[P].next=head[u];head[u]=P;
108     e[++P].to=u;e[P].next=head[v];head[v]=P;
109 }
110 int d[maxn],lpos[maxn],rpos[maxn],tot;
111 void dfs(int u,int fa)
112 {
113     lpos[u]=++tot;
114     for(int i=head[u];i;i=e[i].next)
115     {
116         int v=e[i].to;
117         if(v==fa)continue;
118         d[v]=d[u]+1;
119         dfs(v,u);
120     }
121     rpos[u]=tot;
122 }
123 int main()
124 {
125     scanf("%d%d",&n,&q);
126     for(int i=1;i<n;++i)
127     {
128         int u,v;
129         scanf("%d%d",&u,&v);
130         addedge(u,v);
131     }
132     dfs(1,0);
133     for(int i=1;i<=n;++i)a[i].d[0]=lpos[i],a[i].d[1]=d[i],a[i].size=1;
134     rt=rebuild(1,n,0);
135     while(q--)
136     {
137         int opt,x,y;
138         scanf("%d",&opt);
139         if(opt==1)
140         {
141             scanf("%d%d",&x,&y);
142             p.clear();p.minv[1]=x;p.maxv[1]=x;
143             p.minv[0]=0;p.maxv[0]=inf;
144             add(rt,y);
145         }
146         else
147         {
148             scanf("%d",&x);
149             p.clear();p.minv[0]=lpos[x];p.maxv[0]=rpos[x];
150             p.minv[1]=0;p.maxv[1]=inf;
151             ll ans=query(rt);
152             printf("%lld\n",ans);
153         }
154     }
155     return 0;
156 }

K.

打表发现这样的数最大不超过1000,而且很少

所以把这样的数搜出来,然后每次查询暴力搞就行

 1 #include<bits/stdc++.h>
 2 #define maxn 100005
 3 using namespace std;
 4 int a[maxn];
 5 vector<int> Ans;
 6 bool vis[maxn];
 7 int prime[maxn];
 8 int cnt;
 9 void getprime()
10 {
11     cnt=0;
12     for(int i=2;i<=maxn-5;++i)
13     {
14         if(!vis[i])prime[++cnt]=i;
15         for(int j=1;j<=cnt&&i*prime[j]<=maxn-5;++j)
16         {
17             vis[i*prime[j]]=1;
18             if(!(i%prime[j]))break;
19         }
20     }
21 }
22 bool cho[10];
23 bool check2(int n)
24 {
25     int res=0;
26     for(int i=1;i<=n;++i)if(cho[i])res=res*10+a[i];
27     if(vis[res])return 0;
28     return 1;
29 }
30 bool dfs2(int d,int maxd)
31 {
32     bool pd=1;
33     if(d==maxd+1)return check2(maxd);
34     cho[d]=1;pd=pd&dfs2(d+1,maxd);
35     cho[d]=0;pd=pd&dfs2(d+1,maxd);
36     return pd;
37 }
38 bool check(int n)
39 {
40     if(!dfs2(1,n))return 0;
41     int res=0;
42     for(int i=1;i<=n;++i)res=res*10+a[i];
43     Ans.push_back(res);
44     return 1;
45 }
46 void dfs(int d)
47 {
48     if(d>1&&!check(d-1))return;
49     a[d]=1;dfs(d+1);
50     a[d]=2;dfs(d+1);
51     a[d]=3;dfs(d+1);
52     a[d]=5;dfs(d+1);
53     a[d]=7;dfs(d+1);
54 }
55 int T;
56 char N[maxn];
57 int main()
58 {
59     getprime();
60     dfs(1);
61     sort(Ans.begin(),Ans.end());
62     scanf("%d",&T);
63     for(int cas=1;cas<=T;++cas)
64     {
65         scanf("%s",N+1);
66         int len=strlen(N+1);
67         if(len>3)printf("Case #%d: %d\n",cas,Ans[Ans.size()-1]);
68         else
69         {
70             int ans=0;
71             int val=0;
72             for(int i=1;i<=len;++i)val=val*10+N[i]-'0';
73             for(int i=0;i<Ans.size();++i)if(Ans[i]<=val)ans=Ans[i];
74             printf("Case #%d: %d\n",cas,ans);
75         }
76     }
77     return 0;
78 } 

猜你喜欢

转载自www.cnblogs.com/uuzlove/p/9615565.html
今日推荐