The Contest

直接粗暴贪心 略过

#include<bits/stdc++.h>
using namespace std;
int main()
{//freopen("t.txt","r",stdin);
long long int n,sum=0,k;
scanf("%lld",&n);
for(int i=0;i<n;i++)
{
scanf("%lld",&k);
sum+=k;
}
scanf("%lld",&k);
long long int l,r;
for(int i=0;i<k;i++)
{
scanf("%lld%lld",&l,&r);
if(sum<=r){printf("%lld\n",max(sum,l));return 0;}
}
printf("-1\n");
return 0;
}

The Golden Age

由于指数增长速度极快 直接用一个平衡树遍历即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const LL N=1e18+1;
LL x[100],y[100];
map<LL,LL>s;
int main()
{//freopen("t.txt","r",stdin);
LL l,r;
s.clear();
scanf("%lld%lld%lld%lld",&x[1],&y[1],&l,&r);
x[0]=y[0]=1;
for(int i=2;i<100&&x[i-1]*x[1]<=N&&x[i-1]<=(N/x[1])&&x[i-1]*x[1]>=0&&(!(x[i-1]>1e+9&&x[1]>1e+9));i++)
x[i]=x[i-1]*x[1];
for(int i=2;i<100&&y[i-1]*y[1]<=N&&y[i-1]<=(N/y[1])&&y[i-1]*y[1]>=0&&(!(y[i-1]>1e+9&&y[1]>1e+9));i++)
y[i]=y[i-1]*y[1];
for(int a=0;x[a]<=N&&x[a]!=0;a++)
for(int b=0;y[b]<=N&&y[b]!=0;b++ )
{
//if(a==b)continue;
if(x[a]<0||y[b]<0)continue;
if(x[a]+y[b]<=r&&x[a]+y[b]>=l&&s.count(x[a]+y[b])==0)s[x[a]+y[b]]=1;
}
map<LL,LL>::iterator it,ipt;
LL ans=0,len=0;
s[l-1]=s[r+1]=1;
it=s.begin();
ipt=s.begin();
it++;
for(;it!=s.end();it++,ipt++)
{
//cout<<it->first<<" "<<ipt->first<<endl;
ans=max(ans,it->first-ipt->first-1);
}
printf("%lld\n",ans);
return 0;
}

  

The Tag Game

很简单的贪心 Bob总是要前往最深的节点(在不撞到Alice的前提下)

遍历一下即可

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+1;
int fa[N],dep[N],len[N];
vector<int>adj[N];
int n,x;
int dfs(int cur,int father,int lens)
{
dep[cur]=lens;
len[cur]=0;
fa[cur]=father;
for(int i=0;i<adj[cur].size();i++)
{
int ne=adj[cur][i];
if(ne==father)continue; len[cur]=max(len[cur],dfs(ne,cur,lens+1));
}
return len[cur]+1;
}
int main()
{//freopen("t.txt","r",stdin);
scanf("%d%d",&n,&x);
int a,b;
for(int i=0;i<n;i++)
{
scanf("%d%d",&a,&b);
adj[a].push_back(b);
adj[b].push_back(a);
}
fa[1]=0;
dfs(1,0,0);
int ll=0;
int ans=dep[x]+len[x];
while((x=fa[x])!=0)
{
ll++;
if(dep[x]<=ll)break;
ans=max(ans,dep[x]+len[x]);
}
printf("%d\n",ans*2);
return 0;
}

Two Melodies

O(n^2)的dp 设dp[i][j]为 第一个Melody在i处结束 第二个Melody在j处结束 显然有 dp[i][j]=dp[j][i]

具体转移方法看代码吧 很清晰

# include <iostream>
#include<bits/stdc++.h>
using namespace std;
long long i,j,n,mx,a[5009],b[5009][5009],x[9],y[100009];
int main()
{
cin>>n;
for (i=1;i<=n;i++) cin>>a[i];
for (i=0;i<=n;i++)
{
for (j=0;j<=7;j++) x[j]=0;
for (j=1;j<=n;j++) y[a[j]]=0;
for (j=1;j<i;j++)
{
x[a[j]%7]=max(x[a[j]%7],b[i][j]);
y[a[j]]=max(y[a[j]],b[i][j]);
}
for (j=i+1;j<=n;j++)
{
b[i][j]=max(max(y[a[j]+1],y[a[j]-1]),max(x[a[j]%7],b[i][0]))+1;
b[j][i]=b[i][j];
x[a[j]%7]=max(x[a[j]%7],b[i][j]);
y[a[j]]=max(y[a[j]],b[i][j]);
mx=max(mx,b[i][j]);
}
}
cout<<mx;
}

  

Army Creation

技巧性很强的一道线段树题

我们首先考虑解决一个问题:对于某个士兵,它有可能对哪个区间造成超员?

假设该士兵的位置是d 对于同种类的士兵 往前数k个的位置的士兵 它的位置是b 那么对于区间【1,b】 位置d的士兵会造成他们超员

用线段树可以在对数时间内解决第一个问题。

那么对于题中询问[L,R] 我们只要统计使得区间[L,R]可能超员的士兵 位置小于等于R的个数即可。

总的复杂度 O(nlog^2n)

不过这个代码写的和一般的线段树还不太一样

#include<bits/stdc++.h>
using namespace std; const int Maxn = 100005;
const int Maxm = 524288; int n, k;
int a[Maxn];
vector <int> I[Maxn];
vector <int> st[Maxm];
int q;
int res; void Insert(int v, int l, int r, int a, int b, int val)
{
if (l == a && r == b) st[v].push_back(val);
else {
int m = l + r >> 1;
if (a <= m) Insert(2 * v, l, m, a, min(m, b), val);//重复添加
if (m + 1 <= b) Insert(2 * v + 1, m + 1, r, max(m + 1, a), b, val);
}
} int Get(int v, int l, int r, int x, int R)
{
int res = upper_bound(st[v].begin(), st[v].end(), R) - st[v].begin();
if (l < r) {
int m = l + r >> 1;
if (x <= m) res += Get(2 * v, l, m, x, R);//避免重复计算
else res += Get(2 * v + 1, m + 1, r, x, R);
}
return res;
} int main()
{
scanf("%d %d", &n, &k);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
I[a[i]].push_back(i);
if (I[a[i]].size() > k) Insert(1, 1, n, 1, I[a[i]][I[a[i]].size() - k - 1], i);
}
scanf("%d", &q);
while (q--) {
int x, y; scanf("%d %d", &x, &y);
x = (x + res) % n + 1;
y = (y + res) % n + 1;
if (x > y) swap(x, y);
res = (y - x + 1) - Get(1, 1, n, x, y);
printf("%d\n", res);
}
return 0;
}

  

Bipartite Checking

很具有扩展性的一道题 可以联想到很多问题

官方题解很详细 直接引用

简单概述一下:我们转化问题 对于每条边 我们考虑它覆盖了那些询问 比如对于第i个询问 我们只需要考虑覆盖了它的边即可。

用分治法dfs的时候 我们需要添加边,可以简单做到,删除边该怎么做呢? 把图的信息当作一个栈回溯即可。(分治的过程满足后进先出的性质,所以可以用栈)

复杂度不高,但是常数真的大。

下面引用原文。

If the edges were only added and not deleted, it would be a common problem that is solved with disjoint set union. All you need to do in that problem is implement a DSU which maintains not only the leader in the class of some vertex, but also the distance to this leader. Then, if we try to connect two vertices that have the same leader in DSU and the sum of distances to this leader is even, then we get a cycle with odd length, and graph is no longer bipartite.

But in this problem we need to somehow process removing edges from the graph.

In the algorithm I will describe below we will need to somehow remove the last added edge from DSU (or even some number of last added edges). How can we process that? Each time we change some variable in DSU, we can store an address of this variable and its previous value somewhere (for example, in a stack). Then to remove last added edge, we rollback these changes — we rewrite the previous values of the variables we changed by adding the last edge.

Now we can add a new edge and remove last added edge. All these operations cost (O(logn)) because we won't use path compression in DSU — path compression doesn't work in intended time if we have to rollback. Let's actually start solving the problem.

For convinience, we change all information to queries like "edge (x, y) exists from query number l till query number r". It's obvious that there are no more than q such queries. Let's use divide-and-conquer technique to make a function that answers whether the graph is bipartite or not after every query from some segment of queries [a, b]. First of all, we add to DSU all the edges that are present in the whole segment (and not added yet); then we solve it recursively for  and ; then we remove edges from DSU using the rollback technique described above. When we arrive to some segment [a, a], then after adding the edges present in this segment we can answer if the graph is bipartite after query a. Remember to get rid of the edges that are already added and the edges that are not present at all in the segment when you make a recursive call. Of course, to solve the whole problem, we need to call our function from segment [1, q].

Time complexity is , because every edge will be added only in  calls of the function.

#include<iostream>
#include<cstdio>
#include<map>
#define N 500005
using namespace std;
int n,m,T,fa[N],top,st[N<<2],a[N];
struct E{int x,y,l,r;}e[N];
int Getfa(int x)
{
while (fa[x]!=x) x=fa[x];
return x;
}
int col(int x)//??????
{
int now=0;
while (fa[x]!=x) now^=a[x],x=fa[x];//???????????????
return now;
}
void link(int x,int y,int D)
{ fa[x]=y;a[x]=D;st[++top]=x;
}
void RE(int t)
{
for (;top>t;top--)
fa[st[top]]=st[top],a[st[top]]=0;
}
void work(int l,int r,int k)
{
// cout<<l<<r<<k<<endl;
int mid=(l+r)>>1,now=top;
for (int i=1;i<=k;i++)
if (e[i].l<=l&&r<=e[i].r)//????????????
{ int u=Getfa(e[i].x),v=Getfa(e[i].y);
if (u!=v) link(u,v,col(e[i].x)==col(e[i].y));
else if (col(e[i].x)==col(e[i].y))
{
for(int i=l;i<=r;i++)puts("NO");
RE(now);return;
}
swap(e[k--],e[i--]);
}
if (l==r) puts("YES");
else
{
int i,j;
for (i=1,j=0;i<=k;i++)
if(e[i].l<=mid)swap(e[i],e[++j]);//?????? ??
work(l,mid,j);
for (i=1,j=0;i<=k;i++)
if(e[i].r>mid)swap(e[i],e[++j]);
work(mid+1,r,j);
}
RE(now);//??
}
map<int,int>M[N];
int main()
{ scanf("%d%d",&n,&T);
for (int i=1;i<=T;i++)
{
int x,y;
scanf("%d%d",&x,&y);
if (x>y) swap(x,y);
if (M[x][y]) e[M[x][y]].r=i-1,M[x][y]=0;
else
{
M[x][y]=++m;
e[m].x=x;e[m].y=y;e[m].l=i-1;e[m].r=T;
}
}
for (int i=1;i<=m;i++)
{
// scanf("%d%d%d%d",&e[i].x,&e[i].y,&e[i].l,&e[i].r);
if (++e[i].l>e[i].r) i--,m--;
}
for (int i=1;i<=n;i++)fa[i]=i;
work(1,T,m);
return 0;
}

  

  

Educational Codeforces Round 22 补题 CF 813 A-F的更多相关文章

  1. Educational Codeforces Round 27 补题

    题目链接:http://codeforces.com/contest/845 A. Chess Tourney 水题,排序之后判断第n个元素和n+1个元素是不是想等就可以了. #include < ...

  2. Educational Codeforces Round 23 补题小结

    昨晚听说有教做人场,去补了下玩. 大概我的水平能做个5/6的样子? (不会二进制Trie啊,我真菜) A. 傻逼题.大概可以看成向量加法,判断下就好了. #include<iostream> ...

  3. cordforce Educational Codeforces Round 47 补题笔记 <未完>

    题目链接 http://codeforces.com/contest/1009 A. Game Shopping 直接模拟即可,用了一个队列来存储账单 #include <iostream> ...

  4. Educational Codeforces Round 12补题 经典题 再次爆零

    发生了好多事情 再加上昨晚教育场的爆零 ..真的烦 题目链接 A题经典题 这个题我一开始推公式wa 其实一看到数据范围 就算遍历也OK 存在的问题进制错误 .. 思路不清晰 两个线段有交叉 并不是端点 ...

  5. Educational Codeforces Round 22 E. Army Creation

    Educational Codeforces Round 22 E. Army Creation 题意:求区间[L,R]内数字次数不超过k次的这些数字的数量的和 思路:和求区间内不同数字的数量类似,由 ...

  6. Educational Codeforces Round 22 E. Army Creation(分块好题)

    E. Army Creation time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  7. 【Educational Codeforces Round 22】

    又打了一场EDU,感觉这场比23难多了啊…… 艹还是我太弱了. A. 随便贪心一下. #include<bits/stdc++.h> using namespace std; ,ans=- ...

  8. Educational Codeforces Round 22 E. Army Creation 主席树 或 分块

    http://codeforces.com/contest/813/problem/E 题目大意: 给出长度为n的数组和k,  大小是1e5级别. 要求在线询问区间[l, r]权值,  权值定义为对于 ...

  9. Educational Codeforces Round 22 B. The Golden Age(暴力)

    题目链接:http://codeforces.com/contest/813/problem/B 题意:就是有一个数叫做不幸运数,满足题目的 n = x^a + y^b,现在给你一个区间[l,r],让 ...

随机推荐

  1. [BZOJ4207]Can

    [BZOJ4207]Can 试题描述 这个问题是源于一个在棋盘上玩的,由Sid Sackson设计的名叫Can't stop的游戏的.这个问题与Can't stop有一定的相似之处,但是不需要玩过Ca ...

  2. POJ 2777 Count Color【线段树】

    题目大意:要求完成以下两个操作:1.将一个区间刷上一种颜色2.询问一段区间上有多少种颜色 思路:这两个操作线段树都可以很迅速的完成,具体做法是:线段树上每个节点存这个线段上的颜色数量,由于颜色数很少, ...

  3. THUWC2018 暴力+爆炸记

    Day 0 没有Day0. Day 1 签到然后去宿舍,环境还行,比某偏远山区要强多了,不过这热水有点难拿??看RP有遇到煮好水的饮水机就拿,没有就苟矿泉水. 中午,那个餐还是挺好吃的,不过餐费40就 ...

  4. POJ3233:Matrix Power Series

    对n<=30(其实可以100)大小的矩阵A求A^1+A^2+……+A^K,K<=1e9,A中的数%m. 从K的二进制位入手.K分解二进制,比如10110,令F[i]=A^1+A^2+……+ ...

  5. BZOJ 2308 莫队入门经典

    题目链接  https://www.lydsy.com/JudgeOnline/problem.php?id=2038 参考博客 https://www.cnblogs.com/Paul-Guderi ...

  6. Populating Next Right Pointers in Each Node (DFS,没想到)

    Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *nex ...

  7. lombok注解

    官方文档:@EqualsAndHashCode 转:https://blog.csdn.net/zhanlanmg/article/details/50392266 1. 此注解会生成equals(O ...

  8. ArcGIS Engine中的Symbols详解

    转自原文ArcGIS Engine中的Symbols详解 本文由本人翻译ESRI官方帮助文档.尊重劳动成果,转载请注明来源. Symbols ArcObjects用了三种类型的Symbol(符号样式) ...

  9. IOCP数据中间件

    IOCP数据中间件 每包最大8K(8192字节),超过8187字节的数据要分包传输 首包有5个字节的包头:4字节数据长度(告诉对方,此次总共将传输几字节数据) + 1字节命令字(告诉对方,此次请求的何 ...

  10. android动画具体解释六 XML中定义动画

    动画View 属性动画系统同意动画View对象并提供非常多比view动画系统更高级的功能.view动画系统通过改变绘制方式来变换View对象,view动画是被view的容器所处理的,由于View本身没 ...