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. Pod的创建过程

    Pod是kubernetes中最小的调度单位,里面包含多个容器,也是真正运行你服务的仓库,同一个pod中容器之间资源共享(IP .网络.cpu.mem.挂载目录等). 1.  准备一个yaml(RC/ ...

  2. noip2018 D1T3 赛道修建

    题目描述 C 城将要举办一系列的赛车比赛.在比赛前,需要在城内修建 mm 条赛道. C 城一共有 nn 个路口,这些路口编号为 1,2,…,n1,2,…,n,有 n-1n−1 条适合于修建赛道的双向通 ...

  3. Leetcode_3. Find the longest substring without repeating characters

    3. Find the longest substring without repeating characters Given a string, find the length of the lo ...

  4. ExternalAccessory串口通信

    ExternalAccessory 使用文档 项目下载地址 前言 公司希望通过串口通信的方式实现苹果手机与公司产品进行通信,通过Lighting接口,也就是苹果的数据线.苹果的API External ...

  5. Django_QueryDict

    介绍 class QueryDict(MultiValueDict): """ A specialized MultiValueDict which represents ...

  6. iOS中使用RNCryptor对资源文件加密(先加密后拖进项目中)

    概述:IPA 在发布时,业务相关的敏感资源文件以明文的形式存储,由于没有加密保护,这些文件在应用发布后 可能被其他人获取,并结合其他漏洞和手段产生真实攻击.所以我们要 1.在设计.开发阶段,集合业务确 ...

  7. git push remote: User permission denied

    这种错误因为本地保存了一个错误的账号密码,只需要重新编辑成正确的账号密码 直接上方法

  8. [buaa-SE-2017]个人作业-Week2

    个人作业-Week2 一.代码复审Checklist 1.概要部分 1.1 代码能符合需求和规格说明么? 本次作业的需求可以分成基本的功能实现和大规模数据下程序的健壮性,以及少量的异常处理能力,也就是 ...

  9. 常用算法Java实现之希尔排序

    希尔排序严格来说是基于插入排序的思想,又被称为缩小增量排序. 具体流程如下: 1.将包含n个元素的数组,分成n/2个数组序列,第一个数据和第n/2+1个数据为一对... 2.对每对数据进行比较和交换, ...

  10. iOS 开发学习-import和include的区别

    //当我们在代码中使用两次#include的时候会报错:因为#include相当于拷贝头文件中的声明内容,所以会报重复定义的错误 //但是使用两次#import的话,不会报错,所以他可以解决重复导入的 ...