2020HDU多校第八场By Rynar 6855-6866
1003.Clockwise or Counterclockwise
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node{
ll x,y;
}a[10];
ll xj(node a,node b){
return a.x*b.y-a.y*b.x;
}
signed main(){
int T;
scanf("%d",&T);
while (T--){
for (int i=1;i<=3;i++)scanf("%lld%lld",&a[i].x,&a[i].y);
ll ans=0;
ans=xj(a[1],a[2])+xj(a[2],a[3])+xj(a[3],a[1]);//面积的一半
if (ans<0)puts("Clockwise");
else puts("Counterclockwise");
}
return 0;
}
1004.Discovery of Cycles
思路:LCT
赛时:心态爆炸,%m+1看成了%(m+1),最后没过,赛后改了一下就ac了
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int c[N][2],st[N],fa[N],rev[N],v[N];
int p[N],mn[N],q,kind,n,m,lastans,x,y;
struct use{int st,en;}e[N<<1];
struct node{
int l,r;
friend bool operator<(const node &a,const node &b){
return a.r<b.r;
}
}a[N];
int b[N];
bool isroot(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}
void updata(int x){
int l=c[x][0],r=c[x][1];mn[x]=x;
if (v[mn[l]]<v[mn[x]]) mn[x]=mn[l];
if (v[mn[r]]<v[mn[x]]) mn[x]=mn[r];
}
void pushdown(int x){
int l=c[x][0],r=c[x][1];
if (rev[x]){
rev[l]^=1;rev[r]^=1;rev[x]^=1;
swap(c[x][0],c[x][1]);
}
}
void rotata(int x){
int y=fa[x],z=fa[y],l,r;
if (c[y][0]==x) l=0;else l=1;r=l^1;
if (!isroot(y)){if (c[z][0]==y)c[z][0]=x;else c[z][1]=x;}
fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
c[y][l]=c[x][r];c[x][r]=y;
updata(y);updata(x);
}
void splay(int x){
int top(0);st[++top]=x;
for (int i=x;!isroot(i);i=fa[i]) st[++top]=fa[i];
for (int i=top;i;i--) pushdown(st[i]);
while (!isroot(x)){
int y=fa[x],z=fa[y];
if (!isroot(y)){
if (c[y][0]==x^c[z][0]==y) rotata(x);
else rotata(y);
}
rotata(x);
}
}
void access(int x){int t(0);while (x){splay(x);c[x][1]=t;t=x;updata(x);x=fa[x];}}
void makeroot(int x){access(x);splay(x);rev[x]^=1;}
void link(int x,int y){makeroot(x);fa[x]=y;}
void cut(int x,int y){makeroot(x);access(y);splay(y);c[y][0]=fa[x]=0;}
int que(int x,int y){makeroot(y);access(x);splay(x);return mn[x];}
int find(int x){
access(x);splay(x);
int y=x;
while (c[y][0]) y=c[y][0];
return y;
}
void pre(){
int num=n;
for (int i=1;i<=m;i++){
int x=e[i].st,y=e[i].en;
if (x==y) {p[i]=i;continue;}
if (find(x)==find(y)){
int u=que(x,y),t=v[u];
p[i]=t;cut(e[t].st,u);cut(e[t].en,u);
}
v[++num]=i;mn[num]=num;
link(x,num);link(y,num);
}
}
struct node1{
int val,lazy;
int l,r;
}tr[N<<2];
void pushup1(int rt){
tr[rt].val=max(tr[rt<<1].val,tr[rt<<1|1].val);
}
void putdown1(int rt){
if(tr[rt].lazy){
tr[rt<<1].lazy=tr[rt<<1|1].lazy=tr[rt].lazy;
tr[rt<<1].val=tr[rt<<1|1].val=tr[rt].lazy;
tr[rt].lazy=0;
}
}
void build1(int l,int r,int rt){
tr[rt].l=l;
tr[rt].r=r;
tr[rt].lazy=0;
if (l==r){
tr[rt].val=a[l].l;
return;
}
int mid=(l+r)>>1;
build1(l,mid,rt<<1);
build1(mid+1,r,rt<<1|1);
pushup1(rt);
}
void update1(int l,int r,int add,int rt){
if (l<=tr[rt].l&&r>=tr[rt].r){
tr[rt].lazy=add;
tr[rt].val=add;
return;
}
putdown1(rt);
if(l<=tr[rt<<1].r)
update1(l,r,add,rt<<1);
if(r>=tr[rt<<1|1].l)
update1(l,r,add,rt<<1|1);
pushup1(rt);
}
int query1(int l,int r,int rt){
if(l==tr[rt].l&&r==tr[rt].r)
return tr[rt].val;
putdown1(rt);
if(l>=tr[rt<<1|1].l)
return query1(l,r,rt<<1|1);
else if(r<=tr[rt<<1].r)
return query1(l,r,rt<<1);
else
return max(query1(l,tr[rt<<1].r,rt<<1),query1(tr[rt<<1|1].l,r,rt<<1|1));
}
int cnt=0;
void solve(int x,int y){
if (lastans!=-1)x=(x^lastans)%m+1,y=(y^lastans)%m+1;
if (x>y)swap(x,y);
lastans=0;
int t=upper_bound(b+1,b+1+cnt,y)-b-1;
if (t>0&&query1(1,t,1)>=x)lastans=1;
if (lastans==1)puts("Yes");
else puts("No");
}
int main(){
int T;
scanf("%d",&T);
while (T--){
lastans=-1;
memset(c,0,sizeof c);
memset(st,0,sizeof st);
memset(fa,0,sizeof fa);
memset(v,0x3f,sizeof(v));
memset(rev,0,sizeof rev);
memset(p,0,sizeof p);
memset(mn,0,sizeof mn);
scanf("%d%d%d",&n,&m,&q);
for (int i=0;i<=n+m;i++)mn[i]=i;
for (int i=1;i<=m;i++){
scanf("%d%d",&e[i].st,&e[i].en);
}
pre();
cnt=0;
bool f=0;
for (int i=1;i<=m;i++){
if (p[i])a[++cnt].l=p[i],a[cnt].r=i,f=1;
}
sort(a+1,a+1+cnt);
for (int i=1;i<=cnt;i++){
b[i]=a[i].r;
}
build1(1,cnt,1);
for (int i=1;i<=q;i++){
scanf("%d%d",&x,&y);
if (!f){
puts("No");continue;
}
solve(x,y);
}
}
}
赛后
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
struct LCT{
int tr[N],val[N],fa[N],son[N][2],rev[N];
int top,sta[N];
bool isroot(int t){
return t!=son[fa[t]][0]&&t!=son[fa[t]][1];
}
bool isson(int t){return t==son[fa[t]][1];}
void update(int t){
tr[t]=tr[son[t][0]]^tr[son[t][1]]^val[t];
}
void pushdown(int t){
if (rev[t]){
rev[son[t][0]]^=1,rev[son[t][1]]^=1;
swap(son[t][0],son[t][1]);
rev[t]=0;
}
}
void rotate(int t){
int f=fa[t],g=fa[f],fis=isson(f),tis=isson(t);
fa[t]=g;
if (!isroot(f)) son[g][fis]=t;
fa[son[t][tis^1]]=f,son[f][tis]=son[t][tis^1];
fa[f]=t,son[t][tis^1]=f;
update(f),update(t);
}
void splay(int t){
sta[top=1]=t;
int x=t;
while (!isroot(x))x=fa[x],sta[++top]=x;
while (top)pushdown(sta[top--]);
while (!isroot(t)){
int f=fa[t];
if(isroot(f))rotate(t);
else if(isson(f)==isson(t))rotate(f),rotate(t);
else rotate(t),rotate(t);
}
update(t);
}
void access(int t){//访问
for(int i=0;t;i=t,t=fa[t])
splay(t),son[t][1]=i,update(t);
}
void makeroot(int t){//换根
access(t),splay(t),rev[t]^=1;
}
int findroot(int t){//找根(在真实的树中的)
access(t),splay(t);
while(son[t][0])pushdown(t),t=son[t][0];
splay(t);
return t;
}
void split(int u,int v){//提取路径
makeroot(v),access(u),splay(u);
}
void link(int u,int v){//连边
makeroot(u);
if (findroot(v)!=u)fa[u]=v;
}
void cut(int u,int v){//断边
split(u,v);
if (son[u][0]==v&&!son[v][1])son[u][0]=0,fa[v]=0;
}
}lct;
int u[N],v[N];
int a[N];
int main(){
int T,n,m,q,l,r,lastans;
scanf("%d",&T);
while (T--){
scanf("%d%d%d",&n,&m,&q);
for (int i=1;i<=m;i++){
scanf("%d%d",&u[i],&v[i]);
a[i]=0;
}
int l=1;
for (int i=1;i<=m;i++){
int xx=lct.findroot(u[i]),yy=lct.findroot(v[i]);
while(xx==yy&&l<=i){
a[l]=i;
if (l!=i)lct.cut(u[l],v[l]);
xx=lct.findroot(u[i]),yy=lct.findroot(v[i]);
l++;
}
if (l!=i+1)lct.link(u[i],v[i]);
}
for (int i=l;i<=m;i++)lct.cut(u[i],v[i]);
lastans=-1;
while (q--){
scanf("%d%d",&l,&r);
if (lastans!=-1)l=(l^lastans)%m+1,r=(r^lastans)%m+1;
if (l>r)swap(l,r);
if (a[l]!=0&&a[l]<=r)puts("Yes"),lastans=1;
else puts("No"),lastans=0;
}
}
return 0;
}
1006.Fluctuation Limit
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n;
struct node{
int l,r;
}a[N];
int l[N],r[N];
signed main(){
int T,x;
scanf("%d",&T);
while (T--){
scanf("%d%d",&n,&k);
for (int i=1;i<=n;i++)scanf("%d%d",&a[i].l,&a[i].r);
l[1]=a[1].l,r[1]=a[1].r;
bool f=0;
for (int i=2;i<=n;i++){//左到右
l[i]=l[i-1]-k;r[i]=r[i-1]+k;
if (a[i].l>r[i]||a[i].r<l[i]){
f=1;break;
}
r[i]=min(r[i],a[i].r);
l[i]=max(l[i],a[i].l);
}
for (int i=n-1;i>=1;i--){//右到左
l[i]=max(l[i],l[i+1]-k);r[i]=min(r[i],r[i+1]+k);
r[i]=min(r[i],a[i].r);
l[i]=max(l[i],a[i].l);
}
if (f){
puts("No");continue;
}
puts("Yes");
int x=-1e9;
for (int i=1;i<=n;i++){
if (i!=1)printf(" ");
x=max(x-k,l[i]);
printf("%d",x);
}
puts("");
}
return 0;
}
1008.Hexagon
#include<bits/stdc++.h>
using namespace std;
int a[7]={0,5,6,1,2,3,4};
signed main(){
int T,n,x;
scanf("%d",&T);
while (T--){
scanf("%d",&n);
while (n>2){
int p=n-2;
printf("6");
for (int i=1;i<=6;i++){
printf("%d",i);
for (int j=1;j<=p-(i==6);j++){
printf("%d%d",a[i],i);
}
}
printf("1");
n-=2;
}
if(n==2)printf("612346");
puts("");
}
return 0;
}
1009.Isomorphic Strings
思路:kmp O(nsqrt(n))
#include<bits/stdc++.h>
using namespace std;
const int N=1e7+10;
int n,m,k,d,r;
char s[N];
int nx[N];
int kmp(){
int i=r,j=0;
int len1=r+d*2,len2=d;
while (i<len1&&j<len2){
if (j==-1||s[(i-r)%d+r]==s[j])i++,j++;
else j=nx[j];
}
if (j==len2)return i-j;
else return -1;
}
void getnext(){//nx数组表示前后缀最长的相等串的长度
int len=n;
nx[0]=-1;
int k=-1,j=0;
while (j<len){
if (k==-1||s[j]==s[k]){//p[k]表示前缀,p[j]表示后缀
nx[++j]=++k;
}
else k=nx[k];
}
}
signed main(){
int T,x;
scanf("%d",&T);
while (T--){
scanf("%d%s",&n,s);
getnext();
bool f=1;
for (int k=1;k*k<=n;k++){
if (n%k)continue;
d=k;if (d==n)continue;
f=0;
for (int i=d;i<n;i+=d){
r=i;
if (kmp()==-1){
f=1;
break;
}
}
if (f==0)break;
d=n/k;if (d==n)continue;
f=0;
for (int i=d;i<n;i+=d){
r=i;
if (kmp()==-1){
f=1;
break;
}
}
if (f==0)break;
}
if (f==0)puts("Yes");else puts("No");
}
return 0;
}
1011.Kidnapper's Matching Problem
思路:线性基+kmp
#include<bits/stdc++.h>
using namespace std;
const int maxn=30;
const int N=2e5+10;
const int mod=1e9+7;
int n,m,k;
int q[maxn+1];
int a[N],b[N],nx[N];
int kmp(){
int i=0,j=0,p=1,ans=0;
while (i<n){
if (j==-1||a[i]==b[j]){
if (i>=m)p=2ll*p%mod;
i++,j++;
}
else j=nx[j];
if(j==m){
ans=(1ll*ans+p)%mod;
j=nx[j];
}
}
return ans;
}
void getnext(){//nx数组表示前后缀最长的相等串的长度
nx[0]=-1;
int k=-1,j=0;
while (j<m){
if (k==-1||b[j]==b[k]){
nx[++j]=++k;
}
else k=nx[k];
}
}
void get_lb(int x){
for(int i=maxn;i>=0;i--){
if (!(x>>i))continue;
if (!q[i]){
q[i]=x;break;
}
x^=q[i];
}
}
int get(int x){//消除a,b在S中的bit位
for (int i=maxn;i>=0;i--){
if (x>>i&1)x^=q[i];
}
return x;
}
signed main(){
int T,x;
scanf("%d",&T);
while (T--){
scanf("%d%d%d",&n,&m,&k);
for (int i=0;i<n;i++)scanf("%d",&a[i]);
for (int i=0;i<m;i++)scanf("%d",&b[i]);
memset(q,0,sizeof q);
for (int i=0;i<k;i++){
scanf("%d",&x);
get_lb(x);
}
for (int i=0;i<n;i++)a[i]=get(a[i]);
for (int i=0;i<m;i++)b[i]=get(b[i]);
getnext();
int ans=kmp();
printf("%d\n",ans);
}
return 0;
}
1012.Linuber File System
思路:一定存在一种最优解,使得每个点的它和它所有祖先的操作值之和为li或ri之一或者0
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e3+10;
const int inf=0x3f3f3f3f;
int n,m,cnt;
vector<int>v[N];
int l[N],r[N],p[N];
int dp[N][N];//dp[i][j]为i节点,其父亲及以上具有j个操作值的操作次数
int pre[N],suf[N];
void dfs(int x,int fa){
for (int i=1;i<=cnt;i++)dp[x][i]=0;
for (int i:v[x]){
if (i==fa)continue;
dfs(i,x);
for(int j=1;j<=cnt;j++){
dp[x][j]+=dp[i][j];
}
}
pre[0]=suf[cnt+1]=inf;
for(int i=1;i<=cnt;i++){
pre[i]=min(pre[i-1],((p[i]>=l[x]&&p[i]<=r[x])?dp[x][i]:inf));
}
for(int i=cnt;i>=1;i--){
suf[i]=min(suf[i+1],((p[i]>=l[x]&&p[i]<=r[x])?dp[x][i]:inf));
}
for(int i=1;i<=cnt;i++){
dp[x][i]=min(((p[i]>=l[x]&&p[i]<=r[x])?dp[x][i]:inf),min(pre[i-1],suf[i+1])+1);
}
}
signed main(){
int T,x,y;scanf("%d",&T);
while (T--){
scanf("%d",&n);
for (int i=1;i<=n;i++)v[i].clear();
for (int i=1;i<n;i++){
scanf("%d%d",&x,&y);
v[x].push_back(y);v[y].push_back(x);
}
cnt=0;
for (int i=1;i<=n;i++){
scanf("%d%d",&l[i],&r[i]);
p[++cnt]=l[i];p[++cnt]=r[i];
}
p[++cnt]=0;
sort(p+1,p+1+cnt);
cnt=unique(p+1,p+1+cnt)-p-1;
dfs(1,0);
int pos=lower_bound(p+1,p+cnt+1,0)-p;
cout<<dp[1][pos]<<endl;
}
return 0;
}
禁止类似码农教程的网站爬取,抄袭博客内容。
https://www.cnblogs.com/rair/

浙公网安备 33010602011771号