考场上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 }