D

考虑每个点被删除时其他点对它的贡献,然后发现要求出距离为1~k的点对有多少个。

树分治+FFT。分治时把所有点放一起做一遍FFT,然后减去把每棵子树单独做FFT求出来的值。

复杂度$nlog^2n$

#include<bits/stdc++.h>
#define N 270000
#define pi acos(-1)
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int p = 1000000007;
int pw(int x,int y)
{
int lst=1;
while(y)
{
if(y&1)lst=1LL*lst*x%p;
y>>=1;
x=1LL*x*x%p;
}
return lst;
}
int head[N],ver[2*N],nxt[2*N],tot;
void add(int a,int b)
{
tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=b;return ;
}
struct E
{
double x,y;
E(){;}
E(double _x,double _y)
{
x=_x;y=_y;
}
friend E operator + (E &a,E &b)
{
return E(a.x+b.x,a.y+b.y);
}
friend E operator - (E &a,E &b)
{
return E(a.x-b.x,a.y-b.y);
}
friend E operator * (E &a,E &b)
{
return E(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
}
}a[N],b[N],c[N];
int R[N];
ll ans[N];
void fft(E *a,int f,int n)
{
for(int i=0;i<n;i++)if(i>R[i])swap(a[i],a[R[i]]);
for(int i=1;i<n;i<<=1)
{
E wn(cos(pi/i),f*sin(pi/i));
for(int j=0;j<n;j+=(i<<1))
{
E w(1,0);
for(int k=0;k<i;k++,w=w*wn)
{
E x=a[j+k],y=a[j+k+i]*w;
a[j+k]=x+y;a[j+k+i]=x-y;
}
}
}
if(f==-1)
{
for(int i=0;i<n;i++)a[i].x/=n;
}
return ;
}
void FFT(int *sa,int m,int f)
{
int l=0,n=1;
while(n<=2*m)n<<=1,l++;
for(int i=0;i<n;i++)
{
a[i].y=a[i].x=b[i].x=b[i].y=0;
if(i<=m)a[i].x=b[i].x=sa[i];
}
for(int i=0;i<n;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(l-1));
fft(a,1,n);fft(b,1,n);
for(int i=0;i<n;i++)c[i]=a[i]*b[i];
fft(c,-1,n);
for(int i=2;i<n;i++)
{
ll tmp=(ll)(c[i].x+0.5);
ans[i-1]+=f*tmp;
}
return ;
}
int size[N],mn,id,sum,v[N];
int n;
void dfs(int x,int f)
{
int mx=0;
size[x]=1;
for(int i=head[x];i;i=nxt[i])
{
if(v[ver[i]]||ver[i]==f)continue;
dfs(ver[i],x);
size[x]+=size[ver[i]];
mx=max(mx,size[ver[i]]);
}mx=max(mx,sum-size[x]);
if(mx<mn)
{
mn=mx;
id=x;
}
return ;
}
int now[N],nw[N];
int mxx=0;
void dffs(int x,int f,int dp)
{
size[x]=1;ans[dp]+=2;now[dp]++,nw[dp]++;
if(dp>mxx)mxx=dp;
for(int i=head[x];i;i=nxt[i])
{
if(v[ver[i]]||ver[i]==f)continue;
dffs(ver[i],x,dp+1);
size[x]+=size[ver[i]];
}
return ;
}
void solve(int x)
{
sum=size[x];mn=inf;id=x;
dfs(x,-1);
x=id;
v[x]=1;size[x]=1;ans[1]++;
for(int i=0;i<=sum;i++)now[i]=0;
int mx=0;
for(int i=head[x];i;i=nxt[i])
{
if(v[ver[i]])continue;
mxx=0;
dffs(ver[i],x,2);
size[x]+=size[ver[i]];
FFT(nw,mxx,-1);
mx=max(mx,mxx);
for(int j=0;j<=mxx;j++)nw[j]=0;
}
if(mx)FFT(now,mx,1);
for(int i=head[x];i;i=nxt[i])
{
if(!v[ver[i]])solve(ver[i]);
}
}
int main()
{
scanf("%d",&n);
int t1,t2;
for(int i=1;i<n;i++)
{
scanf("%d%d",&t1,&t2);
add(t1,t2);add(t2,t1);
}
size[1]=n;
solve(1);
ll as=0;
for(int i=1;i<=n;i++)
{
ans[i]%=p;
as+=ans[i]*pw(i,p-2)%p;
}
as%=p;
for(int i=2;i<=n;i++)
{
as=as*i%p;
}
printf("%I64d\n",as);
return 0;
}

 

E

把每条线段看成二维平面上的一个点。

相当于求从(0,0)点到(n+1,n+1)的一条权值和最小的一条路径,且相邻两个点之间不能有其他点。

CDQ分治+单调栈+线段树

和bzoj 4273很像。

#include<bits/stdc++.h>
#define N 100055
#define inf 2147483647
#define ls x<<1,l,mid
#define rs x<<1|1,mid+1,r
using namespace std;
int n;
int p[N],v[N];
int a[N*4];
void gai(int x,int l,int r,int pos,int z)
{
if(l==r)
{
a[x]=z;return ;
}
int mid=(l+r)>>1;
if(pos<=mid)gai(ls,pos,z);
else gai(rs,pos,z);
a[x]=min(a[x<<1],a[x<<1|1]);
return ;
}
int qur(int x,int l,int r,int ll,int rr)
{
if(l>=ll&&r<=rr)return a[x];
int mid=(l+r)>>1;
if(ll>mid)return qur(rs,ll,rr);
if(rr<=mid)return qur(ls,ll,rr);
return min(qur(rs,ll,rr),qur(ls,ll,rr));
}
int st1[N],top1,st2[N],top2;
int q1[N],cnt1,q2[N],cnt2,f[N];
bool cmp(int x,int y)
{
return p[x]<p[y];
}
void solve(int l,int r)
{
if(l==r)return ;
int mid=(l+r)>>1;
solve(l,mid);
top1=top2=cnt1=cnt2=0;
for(int i=l;i<=mid;i++)q1[++cnt1]=i;
for(int i=mid+1;i<=r;i++)q2[++cnt2]=i;
sort(q1+1,q1+cnt1+1,cmp);sort(q2+1,q2+cnt2+1,cmp);
int pt=1;
for(int i=1;i<=cnt2;i++)
{
while(pt<=cnt1&&p[q1[pt]]<=p[q2[i]])
{
while(top1&&st1[top1]<q1[pt])
{
gai(1,1,n,p[st1[top1]],inf);
top1--;
}
gai(1,1,n,p[q1[pt]],f[q1[pt]]+v[q1[pt]]);
st1[++top1]=q1[pt];
pt++;
}
while(top2&&st2[top2]>q2[i])top2--;
int tmp=0;
if(top2)tmp=p[st2[top2]]+1;
f[q2[i]]=min(f[q2[i]],qur(1,1,n,tmp,p[q2[i]]));
st2[++top2]=q2[i];
}
while(top1)gai(1,1,n,p[st1[top1]],inf),top1--;
solve(mid+1,r);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&p[i]);
for(int i=1;i<=n;i++)scanf("%d",&v[i]);
for(int i=1;i<=4*(n+1);i++)a[i]=inf;
p[n+1]=n+1;p[0]=0;
memset(f,0x3f,sizeof(f));
f[0]=0;
solve(0,n+1);
printf("%d\n",f[n+1]);
return 0;
}

  

H

按极角排序,然后用一条线扫过去。

然后狂WA第5个点,去膜了下Claris的代码,发现有些细节写错了。。。

当一个点左右两个点极角比它小的时候,那么答案会加一,否则会减一。

如果连续一条直线上极角都相等,只拿端点算贡献。

然后这些点分为两类,假设现在答案要加一。

如果这个点在右下(意会一下),那么只有扫描线扫过这个点时答案才会加一。

如果在左上,那么扫到这个点时答案已经加了一。

讨论一下,具体看代码。

#include<bits/stdc++.h>
#define N 100005
#define ll long long
using namespace std;
int n;
struct node
{
int x,y;
node(){;}
node(int _x,int _y)
{
x=_x;y=_y;
}
friend node operator - (const node &aa,const node &bb)
{
return node(aa.x-bb.x,aa.y-bb.y);
}
}a[N];
int p[N];
ll cj(const node &aa,const node &bb)
{
return 1LL*aa.x*bb.y-1LL*aa.y*bb.x;
}
bool in[N],ok[N];
bool cmp(int x,int y)
{
return cj(a[x],a[y])>0;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y);
a[0]=a[n];a[n+1]=a[1];
for(int i=1;i<=n;i++)p[i]=i;
sort(p+1,p+n+1,cmp);
int sum=0,ans=0;
for(int i=1;i<=n;)
{
node as=a[p[i]];
int tmp=0;
for(;i<=n&&cj(as,a[p[i]])==0;i++)
{
if(cj(a[p[i]+1],a[p[i]])<0&&cj(a[p[i]-1],a[p[i]])<=0)
{
if(cj(a[p[i]-1]-a[p[i]],a[p[i]+1]-a[p[i]])>0)sum++;
else tmp++;
}
if(cj(a[p[i]+1],a[p[i]])>0&&cj(a[p[i]-1],a[p[i]])>=0)
{
if(cj(a[p[i]-1]-a[p[i]],a[p[i]+1]-a[p[i]])<0)sum--;
else tmp--;
}
}
ans=max(ans,sum);
sum+=tmp;
ans=max(ans,sum);
}
printf("%d\n",ans+1); return 0;
}

  

I

傻逼题,一个子树要么给上边提供一个两个叶子的小子树,要么是一个叶子或零个,其他的只能直接配对,画画图大力分类讨论+贪心。

#include<bits/stdc++.h>
#define N 100005
using namespace std;
int n;
int head[N],ver[N*2],nxt[N*2],tot;
void add(int a,int b)
{
tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=b;return ;
}
int du[N],root;
int ans;
int dfs(int x,int f)
{
int t1=0,t2=0;
int cnt=0;
for(int i=head[x];i;i=nxt[i])
{
if(ver[i]==f)continue;
cnt++;
int tmp=dfs(ver[i],x);
if(tmp==1)t1++;
else if(tmp==2)t2++;
}
if(!cnt)return 1;
while(t2>=2)t2-=2,ans++;
while(t1>=3)t1-=2,ans++;
if(!t1)
{
if(t2==1)return 2;
return 0;
}
if(t1==1)
{
if(t2==1)return 2;
return 1;
}
else
{
if(!t2)return 2;
else if(t2==1){ans++;return 1;}
else {ans++;return 2;}
}
}
int main()
{
scanf("%d",&n);
if(n==2)
{
puts("1");
return 0;
}
int t1,t2;
for(int i=1;i<n;i++)
{
scanf("%d%d",&t1,&t2);
add(t1,t2);add(t2,t1);
du[t1]++;du[t2]++;
}
for(int i=1;i<=n;i++)if(du[i]>1)root=i;
int tmp=dfs(root,-1);
if(tmp==2)ans++;
printf("%d\n",ans);
return 0;
}

  

J

先假设一共有无数个0。

枚举右端点,枚举左端点,然后把中间的1去掉,剩下的操作往里边塞0。

列下式子发现左端点单调,可以用单调队列优化。

最后把ans和0的个数取个min。

#include<bits/stdc++.h>
#define N 1000005
using namespace std;
char s[N];
int n,mx,sum[N];
int q[N];
void solve(int x)
{
int ha=1,ta=1;
q[1]=0;int ans=0;
for(int i=1;i<=n;i++)
{
while(ta>=ha&&sum[i]-sum[q[ha]]>x)ha++;
if(ta>=ha)
{
ans=max(ans,i-2*sum[i]+x+2*sum[q[ha]]-q[ha]);
}
while(ta>=ha&&2*sum[q[ta]]-q[ta]<=2*sum[i]-i)ta--;
q[++ta]=i;
}
printf("%d\n",min(ans,mx));
return ;
}
int main()
{
scanf("%s",s+1);
n=strlen(s+1);
for(int i=1;i<=n;i++)
{
sum[i]=sum[i-1];
if(s[i]=='1')sum[i]++;
}
for(int i=1;i<=n;i++)if(s[i]=='0')mx++;
int q;scanf("%d",&q);
for(int i=1;i<=q;i++)
{
int cnt;scanf("%d",&cnt);
solve(cnt);
}
return 0;
}

  

2016-2017 National Taiwan University World Final Team Selection Contest (Codeforces Gym) 部分题解的更多相关文章

  1. 2016-2017 National Taiwan University World Final Team Selection Contest

    A. Hacker Cups and Balls 二分答案,将$\geq mid$的数看成$1$,$<mid$的数看成$0$,用线段树进行区间排序检查即可.时间复杂度$O(n\log^2n)$. ...

  2. 2016-2017 National Taiwan University World Final Team Selection Contest J - Zero Game

    题目: You are given one string S consisting of only '0' and '1'. You are bored, so you start to play w ...

  3. 2016-2017 National Taiwan University World Final Team Selection Contest C - Crazy Dreamoon

    题目:Statements Dreamoon likes algorithm competitions very much. But when he feels crazy because he ca ...

  4. 2016-2017 National Taiwan University World Final Team Selection Contest A - Hacker Cups and Balls

    题目: Dreamoon likes algorithm competitions very much. But when he feels crazy because he cannot figur ...

  5. sdut 2162:The Android University ACM Team Selection Contest(第二届山东省省赛原题,模拟题)

    The Android University ACM Team Selection Contest Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里 ...

  6. 【转】2016/2017 Web 开发者路线图

    链接:知乎 [点击查看大图] 原图来自LearnCodeAcademy最火的视频,learncode是YouTube上最火的Web开发教学频道,介绍包括HTML/CSS/JavaScript/Subl ...

  7. Moscow Pre-Finals Workshop 2016. National Taiwan U Selection

    A. As Easy As Possible 每个点往右贪心找最近的点,可以得到一棵树,然后倍增查询即可. 时间复杂度$O((n+m)\log n)$. #include <bits/stdc+ ...

  8. Mindjet MindManager 2016/2017 折腾记录

    https://community.mindjet.com/mindjet/topics/ensure-2017-64-bit-version-installation Mindmanager sho ...

  9. [SinGuLaRiTy] COCI 2016~2017 #5

    [SinGuLaRiTy-1012] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 最近神犇喜欢考COCI...... 测试题目 对于所有的 ...

随机推荐

  1. Hyperledger Fabric MSP Identity Validity Rules——MSP身份验证规则

    MSP Identity Validity Rules——MSP身份验证规则 正如Hyperledger Fabric Membership Service Providers (MSP)——成员服务 ...

  2. WPF 自定义 MessageBox (相对完善版 v1.0.0.6)

    基于WPF的自定义 MessageBox. 众所周知WPF界面美观.大多数WPF元素都可以简单的修改其样式,从而达到程序的风格统一.可是当你不得不弹出一个消息框通知用户消息时(虽然很不建议在程序中频繁 ...

  3. JS以及CSS对页面的阻塞

    一.JS阻塞 所有的浏览器在下载JS文件的时候,会阻塞页面上的其他活动,包括其他资源的下载以及页面内容的呈现等等,只有当JS下载.解析.执行完,才会进行后面的 操作.在现代的浏览器中CSS资源和图片i ...

  4. Laravel路由除了根目录全报404错误

    Route::get('hello',function(){ return 'Hello World!'; }); 在laravel/app/Http/routes.php下添加上面的语句,然后再浏览 ...

  5. 第14讲:嵌入式SQL语言(基本技巧)

    一.交互式SQL的局限 & 嵌入式SQL的必要性 专业人员(如DBA)可以熟练地运用交互式SQL语言,但普通用户却不是那么容易上手,所以需要通过数据库应用程序来使用数据库.编写一个可以与数据库 ...

  6. Thunder-Beta发布-事后诸葛亮会议-2017秋-软件工程第十一次作业

    小组名称:Thunder项目名称:爱阅APP小组成员:王航 李传康 翟宇豪 邹双黛 苗威 宋雨 胡佑蓉 杨梓瑞一.设想和目标 1.我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有 ...

  7. Daily Srum 10.28

    这两天我们和其他两组进行了一次会议,主要讨论的是用什么框架来搭建这个平台.在线系统的那一组希望我们用nutch.solr.hbase这一套工具,这对于我们两组来说是一次挑战,毕竟我们一开始用的是关系型 ...

  8. 2018-2019-20172321 《Java软件结构与数据结构》第九周学习总结

    2018-2019-20172321 <Java软件结构与数据结构>第九周学习总结 教材学习内容总结 第15章 图 无向图 图由顶点和边组成. 顶点由名字或标号来表示,如:A.B.C.D: ...

  9. [二叉树建树&完全二叉树判断] 1110. Complete Binary Tree (25)

    1110. Complete Binary Tree (25) Given a tree, you are supposed to tell if it is a complete binary tr ...

  10. 个人作业-Week 3

    案例分析:必应词典 IOS客户端 调研&评测 一.功能性bug bug 1: 症状:在使用拍照翻译这一功能时,只能对图片中的句子逐行进行翻译.即一个中间有换行的句子会被当成两个句子进行翻译. ...