A:甚至连题面都不用仔细看,看一下样例就知道是要把大的和小的配对了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 200010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,id[N],ans[N];
struct data
{
int x,y,i;
bool operator <(const data&a) const
{
return y<a.y;
}
}a[N];
bool cmp(const data&a,const data&b)
{
return a.x>b.x;
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
n=read();
for (int i=1;i<=n;i++) a[i].x=read();
for (int i=1;i<=n;i++) a[i].y=read(),a[i].i=i;
sort(a+1,a+n+1);
for (int i=1;i<=n;i++) id[i]=a[i].i;//��i����id[i]
sort(a+1,a+n+1,cmp);
for (int i=1;i<=n;i++) ans[id[i]]=a[i].x;
for (int i=1;i<=n;i++) printf("%d ",ans[i]);
return 0;
//NOTICE LONG LONG!!!!!
}

  B:vp时拿命想都不会,结果一看sol发现idea还很大一部分是我自己造过的题,简直自闭。显然度数之和应该是偶数,先给不要求度数的随便分配一下满足要求。然后找一棵生成树,自底向上只选树边以满足度数要求即可。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 300010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,m,a[N],p[N],ans[N],u,t;
bool flag[N];
struct data{int to,nxt;
}edge[N<<1];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
void dfs(int k)
{
flag[k]=1;
for (int i=p[k];i;i=edge[i].nxt)
if (!flag[edge[i].to])
{
dfs(edge[i].to);
if (a[edge[i].to]) ans[++u]=(i-1)/2+1,a[k]^=1;
}
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
n=read(),m=read();int cnt=0,cnt2=0;
for (int i=1;i<=n;i++) a[i]=read(),cnt+=(a[i]==-1),cnt2+=(a[i]==1);
if (cnt==0&&(cnt2&1)) {cout<<-1;return 0;}
for (int i=1;i<=n;i++) if (a[i]==-1) if (cnt2&1) cnt2=0,a[i]=1;else a[i]=0;
for (int i=1;i<=m;i++)
{
int x=read(),y=read();
addedge(x,y),addedge(y,x);
}
dfs(1);
cout<<u<<endl;
for (int i=1;i<=u;i++) printf("%d ",ans[i]);
return 0;
//NOTICE LONG LONG!!!!!
}

  C:我省去年初中组直接把这个题搬过来压轴,很久以前口胡过然而并没有写,于是vp时就去搬了份代码交了()。

  显然可以先把每个数的平方因子去掉。然后即相当于要求相邻两数存在不同的质因子。也就相当于要求相邻两数不同。于是把所有数排个序,从小到大考虑每种数,设f[i][j][k]为前i个数当前有j对相同数相邻且其中有k对和当前数相同,转移显然。

  D:显然满足条件的数一定是区间内出现次数前k大的。考虑回滚莫队,维护一下出现次数区间前5大的数即可。稍微卡卡常就行了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
#define N 300010
#define ll long long
int n,m,a[N],b[N],cnt[N],mx[6],ans[N],tmp_mx[6];
struct data
{
int x,y,k,i,u;
bool operator <(const data&a) const
{
return k<a.k||k==a.k&&y<a.y;
}
}q[N];
void ins(int qwq)
{
if (cnt[qwq]<cnt[mx[5]]) return;
int p=0;
for (int k=1;k<=5;k++) if (mx[k]==qwq) {p=k;break;}
if (!p) mx[5]=qwq,p=5;
while (p>1&&cnt[mx[p]]>cnt[mx[p-1]]) swap(mx[p],mx[p-1]),p--;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("b.in","r",stdin);
freopen("b.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read(),m=read();
for (int i=1;i<=n;i++) a[i]=read();
int block=sqrt(n);
for (int i=1;i<=m;i++) q[i].x=read(),q[i].y=read(),q[i].u=read(),q[i].k=q[i].x/block,q[i].i=i;
sort(q+1,q+m+1);
for (int i=1;i<=m;i++)
{
for (int k=1;k<=5;k++) mx[k]=0;
int t=i;while (t<m&&q[t+1].k==q[i].k) t++;
while (i<=t&&q[i].y<(q[i].k+1)*block)
{
for (int j=q[i].x;j<=q[i].y;j++)
{
cnt[a[j]]++;
ins(a[j]);
}
ans[q[i].i]=N;
for (int k=1;k<=5;k++) if (1ll*cnt[mx[k]]*q[i].u>q[i].y-q[i].x+1) ans[q[i].i]=min(ans[q[i].i],mx[k]);
if (ans[q[i].i]==N) ans[q[i].i]=-1;
for (int j=q[i].x;j<=q[i].y;j++) cnt[a[j]]--;
i++;
for (int k=1;k<=5;k++) mx[k]=0;
}
int r=(q[i].k+1)*block-1;
for (int j=i;j<=t;j++)
{
while (r<q[j].y)
{
cnt[a[++r]]++;
ins(a[r]);
}
for (int k=1;k<=5;k++) tmp_mx[k]=mx[k];
for (int k=(q[i].k+1)*block-1;k>=q[j].x;k--)
{
cnt[a[k]]++;
ins(a[k]);
}
ans[q[j].i]=N;
for (int k=1;k<=5;k++) if (1ll*cnt[mx[k]]*q[j].u>q[j].y-q[j].x+1) ans[q[j].i]=min(ans[q[j].i],mx[k]);
if (ans[q[j].i]==N) ans[q[j].i]=-1;
for (int k=(q[i].k+1)*block-1;k>=q[j].x;k--) cnt[a[k]]--;
for (int k=1;k<=5;k++) mx[k]=tmp_mx[k];
}
r=(q[i].k+1)*block-1;
for (int j=i;j<=t;j++)
while (r<q[j].y) cnt[a[++r]]=0;
i=t;
}
for (int i=1;i<=m;i++) printf("%d\n",ans[i]);
return 0;
}

  事实上直接拿棵主席树在上面暴力查询复杂度大约就是O(knlogn)。具体并不会证。感觉很对就行了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 300010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,m,root[N],a[N],cnt;
struct data{int l,r,x;
}tree[N<<5];
void ins(int &k,int l,int r,int x)
{
tree[++cnt]=tree[k];k=cnt;tree[k].x++;
if (l==r) return;
int mid=l+r>>1;
if (x<=mid) ins(tree[k].l,l,mid,x);
else ins(tree[k].r,mid+1,r,x);
}
int query(int x,int y,int l,int r,int u)
{
if (tree[y].x-tree[x].x<=u) return -1;
if (l==r) return l;
int mid=l+r>>1;
int v=query(tree[x].l,tree[y].l,l,mid,u);
if (v==-1) return query(tree[x].r,tree[y].r,mid+1,r,u);
else return v;
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
n=read(),m=read();
for (int i=1;i<=n;i++) a[i]=read();
for (int i=1;i<=n;i++)
{
root[i]=root[i-1];
ins(root[i],1,n,a[i]);
}
for (int i=1;i<=m;i++)
{
int l=read(),r=read(),x=read();
printf("%d\n",query(root[l-1],root[r],1,n,(r-l+1)/x));
}
return 0;
//NOTICE LONG LONG!!!!!
}

  E:因为用来异或的dist随祖先深度减小连续递增,考虑一个套路的对位运算的分块,即固定高位的前一半数字,不妨设令其去掉后9位的部分相同。那么即对于每个点,考虑其向上29个点作为一块。对于每一块,考虑以前一半数字建trie,叶子处存储ai^x的最大值,其中x是其与该块下端点的深度差,因为深度差的后9位对于该块每个点来说在所有需要用到该块的查询中都是一样的。这样预处理的复杂度是7*29*n。考虑查询,从查询点往上暴跳考虑每个块,如果块不完整显然暴力即可,否则先对前一半数字trie上按位贪心,贪完之后即可固定答案中点i的ai前一半数字,并且可以发现答案已经被预处理出来了。查询复杂度q*(29+n*7/29)。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 50010
#define M 150010
#define BLOCK 512
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,m,a[N],p[N],fa[N],fa512[N],deep[N],root[N],f[N][N/BLOCK+10],trie[N*256][2],t,cnt;
struct data{int to,nxt;
}edge[N<<1];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
void dfs(int k)
{
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=fa[k])
{
fa[edge[i].to]=k;
deep[edge[i].to]=deep[k]+1;
dfs(edge[i].to);
}
}
void ins(int &k,int x)
{
if (!k) k=++cnt;
for (int i=k,j=6;j>=0;j--)
{
if (!trie[i][(x&(1<<j))>0]) trie[i][(x&(1<<j))>0]=++cnt;
i=trie[i][(x&(1<<j))>0];
}
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
n=read(),m=read();
for (int i=1;i<=n;i++) a[i]=read();
for (int i=1;i<n;i++)
{
int x=read(),y=read();
addedge(x,y),addedge(y,x);
}
dfs(1);
for (int i=1;i<=n;i++)
if (deep[i]>=BLOCK)
{
fa512[i]=i;
for (int j=0;j<BLOCK;j++)
{
int x=fa512[i];
ins(root[i],a[x]>>9);
f[i][a[x]>>9]=max(f[i][a[x]>>9],a[x]^j);
fa512[i]=fa[fa512[i]];
}
}
for (int i=1;i<=m;i++)
{
int y=read(),x=read(),u=x,v=0,ans=0;
while (deep[u]-deep[y]>=BLOCK)
{
int w=0;
for (int k=root[u],j=6;j>=0;j--)
if (v&(1<<j))
{
if (trie[k][0]) k=trie[k][0],w=w<<1;
else k=trie[k][1],w=w<<1|1;
}
else
{
if (trie[k][1]) k=trie[k][1],w=w<<1|1;
else k=trie[k][0],w=w<<1;
}
ans=max(ans,f[u][w]^(v<<9));u=fa512[u];v++;
}
while (u!=y) ans=max(ans,a[u]^deep[x]-deep[u]),u=fa[u];
ans=max(ans,a[y]^deep[x]-deep[y]);
printf("%d\n",ans);
}
return 0;
//NOTICE LONG LONG!!!!!
}

  

Codeforces Round #429 Div. 1的更多相关文章

  1. CodeForces 840C - On the Bench | Codeforces Round #429 (Div. 1)

    思路来自FXXL中的某个链接 /* CodeForces 840C - On the Bench [ DP ] | Codeforces Round #429 (Div. 1) 题意: 给出一个数组, ...

  2. CodeForces 840B - Leha and another game about graph | Codeforces Round #429(Div 1)

    思路来自这里,重点大概是想到建树和无解情况,然后就变成树形DP了- - /* CodeForces 840B - Leha and another game about graph [ 增量构造,树上 ...

  3. CodeForces 840A - Leha and Function | Codeforces Round #429 (Div. 1)

    /* CodeForces 840A - Leha and Function [ 贪心 ] | Codeforces Round #429 (Div. 1) A越大,B越小,越好 */ #includ ...

  4. 【Codeforces Round #429 (Div. 2) A】Generous Kefa

    [Link]:http://codeforces.com/contest/841/problem/A [Description] [Solution] 模拟,贪心,每个朋友尽量地多给气球. [Numb ...

  5. Codeforces Round #429 (Div. 2/Div. 1) [ A/_. Generous Kefa ] [ B/_. Godsend ] [ C/A. Leha and Function ] [ D/B. Leha and another game about graph ] [ E/C. On the Bench ] [ _/D. Destiny ]

    PROBLEM A/_ - Generous Kefa 题 OvO http://codeforces.com/contest/841/problem/A cf 841a 解 只要不存在某个字母,它的 ...

  6. 【Codeforces Round #429 (Div. 2) C】Leha and Function

    [Link]:http://codeforces.com/contest/841/problem/C [Description] [Solution] 看到最大的和最小的对应,第二大的和第二小的对应. ...

  7. 【Codeforces Round #429 (Div. 2) B】 Godsend

    [Link]:http://codeforces.com/contest/841/problem/B [Description] 两个人轮流对一个数组玩游戏,第一个人可以把连续的一段为奇数的拿走,第二 ...

  8. Codeforces Round #429 (Div. 2) 补题

    A. Generous Kefa 题意:n个气球分给k个人,问每个人能否拿到的气球都不一样 解法:显然当某种气球的个数大于K的话,就GG了. #include <bits/stdc++.h> ...

  9. Codeforces Round #429 (Div. 1) C. On the Bench(dp + 组合数)

    题意 一个长度为 \(n\) 的序列 \(A\) ,定义一个 \(1\) 到 \(n\) 的排列 \(p\) 是合法的,当且仅当 \(\forall i \in [1, n − 1], A_{p_i} ...

随机推荐

  1. linux cgroups 简介

    cgroups(Control Groups) 是 linux 内核提供的一种机制,这种机制可以根据需求把一系列系统任务及其子任务整合(或分隔)到按资源划分等级的不同组内,从而为系统资源管理提供一个统 ...

  2. 【Java并发.2】线程安全性

    要编写线程安全的代码,其核心在于要对状态访问操作进行管理,特别是对共享(Shared)和可变的(Mutable)状态的访问. “共享”意味着变量可以由多个线程同时访问,而“可变”则意味着变量的值在其生 ...

  3. Java调度池的实现原理

    下图是关于ScheduledFutureTask的继承体系结构图.

  4. python-Requests + 正则表达式爬取猫眼电影

    github: https://github.com/LXL-YAN/Requests_Regular-Expressions-Crawl-CatEye-Movies

  5. SpringCloud微服务架构分布式组件如何共享session对象

    一.简单做一个背景说明1.为说明问题,本文简单微服务架构示例如下 2.组件说明分布式架构,每个组件都是集群或者主备.具体说明如下:zuul service:网关,API调用都走zuul service ...

  6. 结对项目3-功能增强型带基本函数计算java计算器

    -----------------------------------------------------实验报告------------------------------------------- ...

  7. Servlet 使用ServletContext共享数据,读取web.xml配置

    ServletContext对象 session和cookie,对于每一个请求用户来说,都是不同的,因为要保证隐私安全. 而有一些数据,可以让所有用户共享,此时就可以用ServletContext对象 ...

  8. 使用ajax请求后端程序时,关于目标程序路径问题

    这里涉及到和PHP中类似的问题,有待更新!!!

  9. css行内省略号、垂直居中

    应用场景分析: 一.当你的文字限定行数,超出部分的文字用省略号显示. (有两个使用场景:1.单行 2.多行) // 单行 overflow: hidden; text-overflow:ellipsi ...

  10. java.util.Collections.copy():列表List浅拷贝

    今天同事问我怎样将一个列表(list1)拷贝到另一个列表(list2),然后修改新的列表(list2)不会影响到旧的列表(list1),想了一想,这是深拷贝啊. 可是,除了循环new还有别的办法吗,想 ...