# 补题（2016-2017区域赛）

2016 ICPC Dalian, by Avalon
Board: http://board.acmicpc.info/icpc2016/dlmu_onsite.php
Solved Now: 10/11

Problem B
http://acm.hdu.edu.cn/showproblem.php?pid=5972
Code:

#include <bits/stdc++.h>
using namespace std;
int n;
bitset<1003>b[10];
char s[5000003];
int main(){
while(~scanf("%d",&n)){
for(int i=0;i<10;i++)b[i].reset();
for(int i=0;i<n;i++){
int k;
scanf("%d",&k);
for(int j=0;j<k;j++){
int x;
scanf("%d",&x);
b[x].set(i);
}
}
int m=strlen(s);
bitset<1003>ans;
for(int i=0;i<m;i++){
ans<<=1;
ans.set(0);
ans&=b[s[i]-'0'];
if(ans[n-1]){
fwrite(s+i-n+1,1,n,stdout);
putchar('\n');
}
}
}
}

Key: BITSET Shift-And FastIO

Problem K
http://acm.hdu.edu.cn/showproblem.php?pid=5981
Code:

#include <bits/stdc++.h>
using namespace std;
const int mod=100000073;
typedef long long ll;
ll dp[5000003];
ll sum[5000003];
int main(){
dp[1]=1;dp[2]=2;
sum[1]=1;sum[2]=3;
int l=1,r=1;
for(int i=3;i<=5000000;i++){
while(dp[l+1]+l+1<=i-1)l++;
dp[i]=i-l;
while(dp[r+1]<=dp[i]-1)r++;
sum[i]=sum[r]-sum[l-1]+sum[i-1]+mod;
while(sum[i]>mod)sum[i]-=mod;
}
int x,y;
while(~scanf("%d%d",&x,&y)){
x=y-x+1;
printf("%lld %lld\n",dp[x],(sum[x]-sum[x-1]+mod)%mod);
}
}

Key: DP 2-Pointer

2016 ICPC Qingdao, by Avalon
No Official Board
Replay Board: https://vjudge.net/contest/142308#rank
Solved Now: 6/13

Problem K
http://acm.hdu.edu.cn/showproblem.php?pid=5992
Code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF=1ll<<60;
struct node{
int d[3],ma[3],mi[3],l,r,id;
}T[200003];
int rt,n,m,cmp_d;
inline bool cmp(node a,node b){
return a.d[cmp_d]<b.d[cmp_d];
}
inline void up(int u,int v){
T[u].ma[0]=max(T[u].ma[0],T[v].ma[0]);
T[u].ma[1]=max(T[u].ma[1],T[v].ma[1]);
T[u].ma[2]=max(T[u].ma[2],T[v].ma[2]);
T[u].mi[0]=min(T[u].mi[0],T[v].mi[0]);
T[u].mi[1]=min(T[u].mi[1],T[v].mi[1]);
T[u].mi[2]=min(T[u].mi[2],T[v].mi[2]);
}
inline int build(int l,int r,int D){
int mid=(l+r)>>1;
cmp_d=D;
nth_element(T+l,T+mid,T+r+1,cmp);
T[mid].ma[0]=T[mid].mi[0]=T[mid].d[0];
T[mid].ma[1]=T[mid].mi[1]=T[mid].d[1];
T[mid].ma[2]=T[mid].mi[2]=T[mid].d[2];

if(l!=mid){
T[mid].l=build(l,mid-1,(D+1)%3);
up(mid,T[mid].l);
}
if(r!=mid){
T[mid].r=build(mid+1,r,(D+1)%3);
up(mid,T[mid].r);
}
return mid;
}

ll dis;
int ans;
int x,y,c;
//估计范围
inline ll getdis(int p){
ll ret=0;
if(T[p].mi[2]>c)return INF;
if(x>T[p].ma[0])ret+=1ll*(x-T[p].ma[0])*(x-T[p].ma[0]);
if(x<T[p].mi[0])ret+=1ll*(T[p].mi[0]-x)*(T[p].mi[0]-x);
if(y>T[p].ma[1])ret+=1ll*(y-T[p].ma[1])*(y-T[p].ma[1]);
if(y<T[p].mi[1])ret+=1ll*(T[p].mi[1]-y)*(T[p].mi[1]-y);
return ret;
}
inline void query(int p){
ll d0=1ll*(x-T[p].d[0])*(x-T[p].d[0])+1ll*(y-T[p].d[1])*(y-T[p].d[1]);
if(T[p].d[2]>c)d0=INF;
if(d0<dis||(d0==dis&&T[p].id<T[ans].id)){
dis=d0;
ans=p;
}
ll dl=INF,dr=INF;
if(T[p].l)dl=getdis(T[p].l);
if(T[p].r)dr=getdis(T[p].r);
if(dl<dr){
if(dl<=dis)query(T[p].l);
if(dr<=dis)query(T[p].r);
}
else {
if(dr<=dis)query(T[p].r);
if(dl<=dis)query(T[p].l);
}
}
int main(){
int tt;
scanf("%d",&tt);
while(tt--){
memset(T,0,sizeof(T));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&T[i].d[0],&T[i].d[1],&T[i].d[2]);
T[i].id=i;
}
rt=build(1,n,0);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&c);
ans=0;
dis=INF;
query(rt);
printf("%d %d %d\n",T[ans].d[0],T[ans].d[1],T[ans].d[2]);
}
}
}

Key: KD-Tree
Referred to:
https://blog.csdn.net/jiangshibiao/article/details/34144829

2016 ICPC China-Final, by Avalon
Board: http://codeforces.com/gym/101194/standings
Solved Now: 8/13

#include <bits/stdc++.h>
using namespace std;
int n,m,q;
int a[200003];
int f[200003];
int siz[200003];
int fa[200003][20];
int fal[200003][20];
int ms[200003];
int tot;
int tim[200003];
int mx;
set<int>st[100003];
int tmp;
int ans[200003];
bool vis[200003];
struct edge{
int u,v,w;
}rec[200003];
bool cmp(edge a,edge b){
return a.w<b.w;
}
struct Edge{
int to,next;
}e[400003];
int cnt;
void add(int u,int v){
e[cnt].to=v;
}

int getfa(int u){
if(f[u]==0)return u;
return f[u]=getfa(f[u]);
}
void Union(int u,int v,int w){
u=getfa(u);
v=getfa(v);
if(u==v)return ;
tot++;
f[u]=tot;
f[v]=tot;
fa[u][0]=tot;
fa[v][0]=tot;
fal[u][0]=w;
fal[v][0]=w;
}
void dfs(int u){
siz[u]=true;
vis[u]=true;
ms[u]=-1;
int v=e[i].to;
if(vis[v])continue;
dfs(v);
siz[u]+=siz[v];
if(ms[u]==-1||siz[ms[u]]<siz[v])ms[u]=v;
}
}
if(a[u]==-1)return;
int p=++tim[a[u]];
if(p==1){
st[p].insert(a[u]);
}
else {
st[p-1].erase(a[u]);
st[p].insert(a[u]);
}
if(p>mx){
mx=p;
tmp=a[u];
}
else if(p==mx){
tmp=min(tmp,a[u]);
}
}
void del(int u){
if(a[u]==-1)return ;
int p=--tim[a[u]];
if(p==0){
st[p+1].erase(a[u]);
}
else {
st[p+1].erase(a[u]);
st[p].insert(a[u]);
}
if(st[mx].empty()){
--mx;
if(mx==0)tmp=0;
else tmp=*(st[mx].begin());
}
}
int v=e[i].to;
}
}
void deltree(int u){
del(u);
int v=e[i].to;
deltree(v);
}
}
void dfs2(int u){
vis[u]=true;
if(ms[u]==-1){
ans[u]=tmp;
return;
}
int v=e[i].to;
if(v==ms[u])continue;
dfs2(v);
deltree(v);
}
dfs2(ms[u]);
int v=e[i].to;
if(v==ms[u])continue;
}
ans[u]=tmp;
}
void init(){
memset(a,-1,sizeof(a));
memset(f,0,sizeof(f));
tot=n;
cnt=0;
memset(fa,0,sizeof(fa));
mx=0;
for(int i=1;i<=n;i++)st[i].clear();
}
void printtree(){
for(int i=1;i<=tot;i++)printf("%d%c",a[i],i==tot?'\n':' ');
for(int u=1;u<=tot;u++){
int v=e[i].to;
cout<<u<<' '<<v<<' '<<fal[v]<<endl;
}
}
}
void printans(){
for(int i=1;i<=tot;i++){
printf("%d %d\n",i,ans[i]);
}
}
void debug(){
printtree();
printans();
}
int main(){
int T;
scanf("%d",&T);
for(int tt=1;tt<=T;tt++){
scanf("%d%d",&n,&m);
init();
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=1;i<=m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
rec[i]=(edge){u,v,w};
}
sort(rec+1,rec+1+m,cmp);
for(int i=1;i<=m;i++){
Union(rec[i].u,rec[i].v,rec[i].w);
}
memset(vis,false,sizeof(vis));
for(int i=tot;i>=1;i--){
if(!vis[i]){
dfs(i);
}
}
memset(vis,false,sizeof(vis));
for(int i=tot;i>=1;i--){
if(!vis[i]){
dfs2(i);
deltree(i);
}
}
memset(vis,false,sizeof(vis));
for(int j=1;j<=18;j++){
for(int i=1;i<=tot;i++){
fa[i][j]=fa[fa[i][j-1]][j-1];
fal[i][j]=fal[fa[i][j-1]][j-1];
}
}
int q;
scanf("%d",&q);
printf("Case #%d:\n",tt);
int last=0;
while(q--){
int x,y;
scanf("%d%d",&x,&y);
x^=last;
y^=last;
for(int j=18;j>=0;j--){
if(fa[x][j]==0)continue;
if(fal[x][j]<=y)x=fa[x][j];
}
last=ans[x];
printf("%d\n",last);
}
}
}

Key: MST 启发式合并 树上倍增

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=305000;
char str[maxn];
int s[maxn];
int sa[maxn], t[maxn], t2[maxn], c[maxn], n;
int Rank[maxn], height[maxn];
int u[maxn], d[maxn];
void build_sa(int m, int n){
int i, *x=t, *y=t2;
for(i=0;i<m;i++)c[i]=0;
for(i=0;i<n;i++)c[x[i]=s[i]]++;
for(i=1;i<m;i++)c[i]+=c[i-1];
for(i=n-1;i>=0;i--)sa[--c[x[i]]]=i;
for(int k=1;k<=n;k<<=1){
int p=0;
for(i=n-k;i<n;i++)y[p++]=i;
for(i=0;i<n;i++)if(sa[i]>=k)y[p++]=sa[i]-k;
for(i=0;i<m;i++)c[i]=0;
for(i=0;i<n;i++)c[x[y[i]]]++;
for(i=1;i<m;i++)c[i]+=c[i-1];
for(i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i];
swap(x, y);
p=1;x[sa[0]]=0;
for(i=1;i<n;i++)
x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
if(p>=n)break;
m=p;
}
}
void geth(int n){
int i, j, k=0;
for(i=0;i<n;i++)Rank[sa[i]]=i;
for(i=0;i<n;i++){
if(k)k--;
if(Rank[i]==0)break;
j=sa[Rank[i]-1];
while(s[i+k]==s[j+k])k++;
height[Rank[i]]=k;
}
}
int main()
{
int T;
scanf("%d", &T);
for(int t=1;t<=T;t++){
int q;
scanf("%d", &q);
n=0;
int f1=0;
for(int i=1;i<=q;i++){
scanf("%s", str);
int len=strlen(str);
for(int j=0;j<len;j++){
s[n++]=str[j]-'a'+1;
}
if(i==1){
f1=len;
s[n++]=30;
}
else s[n++]=0;
}
build_sa(31, n);
geth(n);
int l, r;
int st=-1;
int len=n;
for(int i=1;i<n;i++){
if(sa[i]>=f1)continue;
l=i, r=i;
while(sa[r]<f1)r++;
u[l]=height[l];
for(int j=l+1;j<r;j++)u[j]=min(height[j], u[j-1]);
d[r-1]=height[r];
for(int j=r-2;j>=l;j--)d[j]=min(height[j+1], d[j+1]);
for(int j=l;j<r;j++){
int M=max(u[j], d[j]);
if(M+1<=f1-sa[j]&&M+1<len){
len=M+1;
st=sa[j];
}
}
i=r;
}
printf("Case #%d: ", t);
if(st==-1)printf("Impossible\n");
else {
for(int i=0;i<len;i++)printf("%c", s[st+i]+'a'-1);
printf("\n");
}
}
}

Key: SA