A. Vladik and Courtesy

水题略过

#include<cstdio>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long int LL;
int main()
{
LL a,b;
scanf("%I64d%I64d",&a,&b);
LL num=1;
while(true)
{
if(a<num){printf("Vladik\n");return 0;}
a-=num;
//b+=num;
num++;
if(b<num){printf("Valera\n");return 0;}
b-=num;
//a+=num;
num++;
}
return 0;
}

B. Vladik and Complicated Book

给定一个序列, 询问子区间【l,r】的第k小数是不是原位置的数。

显然可以用主席树维护,不过这道题数据放水了,用暴力一点的方法应该也能过。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100000 + 5; int a[N], b[N], rt[N * 20], ls[N * 20], rs[N * 20], sum[N * 20],numm[N]; int n, k, tot, sz, ql, qr, x, q, T; void Build(int& o, int l, int r){
if(l>r)return ;
o = ++ tot;
sum[o] = 0;
if(l == r) return;
int m = (l + r) >> 1;
Build(ls[o], l, m);
Build(rs[o], m + 1, r);
} void update(int& o, int l, int r, int last, int p){
o = ++ tot;
ls[o] = ls[last];
rs[o] = rs[last];
sum[o] = sum[last] + 1;
if(l == r) return;
int m = (l + r) >> 1;
if(p <= b[m]) update(ls[o], l, m, ls[last], p);
else update(rs[o], m + 1, r, rs[last], p);
} int query(int ss, int tt, int l, int r, int k){
if(l == r) return l;
int m = (l + r) >> 1;
int cnt = sum[ls[tt]] - sum[ls[ss]];
if(k <= cnt) return query(ls[ss], ls[tt], l, m, k);
else return query(rs[ss], rs[tt], m + 1, r, k - cnt);
} void work(){
scanf("%d%d%d", &ql, &qr, &x);
int xx=x;
x=(xx-ql+1);
int ans = query(rt[ql - 1], rt[qr], 1, sz, x);
if(b[ans]==numm[xx])printf("Yes\n");
else printf("No\n");
} int main(){//freopen("t.txt","r",stdin);
T=1;
while(T--){
scanf("%d%d", &n, &q);
for(int i = 1; i <= n; i ++) scanf("%d", a + i), numm[i]=b[i] = a[i];
sort(b + 1, b + n + 1);
sz = unique(b + 1, b + n + 1) - (b + 1);
tot = 0;
Build(rt[0],1, sz);
//for(int i = 0; i <= 4 * n; i ++)printf("%d,rt = %d,ls = %d, rs = %d, sum = %d\n", i, rt[i], ls[i], rs[i], sum[i]);
//for(int i = 1; i <= n; i ++)a[i] = lower_bound(b + 1, b + sz + 1, a[i]) - b;
for(int i = 1; i <= n; i ++)update(rt[i], 1, sz, rt[i - 1], a[i]);
// for(int i = 0; i <= 5 * n; i ++)printf("%d,rt = %d,ls = %d, rs = %d, sum = %d\n", i, rt[i], ls[i], rs[i], sum[i]);
while(q --)work();
}
return 0;
}

C. Vladik and Memorable Trip

O(n^2)的线性dp 不要想太多。。(我都想到DAG去了。。。)

代码比较简单,可以直接看懂。

#include <bits/stdc++.h>
using namespace std; vector <int> ps [5010], cs[5010];
int s[5010] , e[5010];
bool vis[5010];
long long dp [5010];
int main()
{
int n;
scanf("%d",&n);
vector <int> a (n);
for (int i = 0; i < n; i++) {
scanf("%d",&a[i]);
if (!vis[a[i]]) s[a[i]] = i;
vis[a[i]] = 1;
e[a[i]] = i;
}
for (int i = 0; i < n; i++) vis[a[i]] = 0;
for (int i = 0; i < n; i++) {
int mx = i, rx = 0, lj = i;
for (int j = i; j < n; j++) {
if (s[a[j]] < i) break;
lj = j;
mx = max(mx,e[a[j]]);
if (!vis[a[j]]) rx ^= a[j];
vis[a[j]] = 1; if (mx <= j) {
ps[i].push_back(j);
cs[i].push_back(rx);
}
}
for (int k = lj; k >= i; k--) vis[a[k]] = 0;
}
for (int i = n-1; i >= 0; i--) {
dp[i] = dp[i+1];
for (int j = 0; j < ps[i].size(); j++) {
dp[i] = max(dp[i],dp[ps[i][j]+1]+cs[i][j]);
}
}
printf("%I64d\n",dp[0]);
}

D. Vladik and Favorite Game

第一步判断一下按钮是否反转即可。剩下的直接暴力求路径,水题。

#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define ff first
#define ss second
#define pb push_back const int N = 100 + 11; int use[N][N];
char a[N][N],b[5];
vector<pair<int,int> > v,w;
vector<int> vv; void dfs(int l, int r)
{
use[l][r]=1;
v.pb(mp(l,r));
if (a[l][r]=='F') {w=v; return;}
if (use[l-1][r]==0&&(a[l-1][r]=='.'||a[l-1][r]=='F')) dfs(l-1,r);
if (use[l+1][r]==0&&(a[l+1][r]=='.'||a[l+1][r]=='F')) dfs(l+1,r);
if (use[l][r-1]==0&&(a[l][r-1]=='.'||a[l][r-1]=='F')) dfs(l,r-1);
if (use[l][r+1]==0&&(a[l][r+1]=='.'||a[l][r+1]=='F')) dfs(l,r+1);
v.pop_back();
}
int main()
{
int n,m;
cin>>n>>m;
int l,r;
for (int i=1; i<=n; i++)
for (int j=1; j<=m; j++)
{
cin>>a[i][j];
if (a[i][j]=='F') {l=i; r=j;}
}
b[1]='L';
b[2]='R';
b[3]='U';
b[4]='D';
dfs(1,1);
for (int i=1; i<w.size(); i++)
{
if (w[i].ff==w[i-1].ff)
{
if (w[i].ss==w[i-1].ss-1) vv.pb(1); else vv.pb(2);
} else
if (w[i].ff==w[i-1].ff-1) vv.pb(3); else vv.pb(4);
}
int u1=0,u2=0;
int x=1,y=1;
for (int i=0; i<vv.size(); i++)
{
if (vv[i]==2&&u1==0)
{
cout<<"R"<<endl;
int xx,yy;
cin>>xx>>yy;
u1=1;
if (x==xx&&y==yy) {swap(b[1],b[2]); cout<<"L"<<endl; cin>>x>>y;}
} else
if (vv[i]==4&&u2==0)
{
cout<<"D"<<endl;
int xx,yy;
cin>>xx>>yy;
u2=1;
if (x==xx&&y==yy) {swap(b[3],b[4]); cout<<"U"<<endl; cin>>x>>y;}
} else
{
cout<<b[vv[i]]<<endl;
cin>>x>>y;
}
} }

  

E. Vladik and Entertaining Flags

线段树+并查集

给定一个行数为10 列数10w的矩阵,每个方块是一个整数, 给定l和r 求范围内的联通块数量 所谓联通块即数字相等。

考虑用二分的方法合并两个联通块,在合并的时候只需要标记边界的元素属于哪个块即可,不用考虑块内的元素,因为它们不会在将来的合并中使用到。

这样我们就可以做到在常数时间内合并两个块了,这样用线段树维护就没有问题了。

其实想了一下,用倍增的方法也是可以的,dp[i][k]表示从第i列开始 连续2^k列的联通块,复杂度也是O(nlogn)

所以用一个线段树维护所有的[l,r]子块,每次查询线段树即可,合并的时候要重新标号。

重点:对于每个子块,我们只需要知道边界上的元素属于这个子块的哪个联通分量即可(使用并查集维护)

比赛的时候我也是老想块中的元素怎么维护,就觉得二分难搞了,其实完全不需要考虑。。

#include <bits/stdc++.h>

using namespace std;

const int N = 10;
const int M = 100010; int n, m, q;
int a[N][M];
int state[50], mark[50]; struct Info{
int cnt;
int left[N];
int right[N]; Info() {
cnt = 0;
memset(left, 0, sizeof left);
memset(right, 0, sizeof right);
}
} tr[M << 2]; Info join(Info &u, Info &v, int p) {
Info f;
f.cnt = u.cnt + v.cnt;
memset(state, 0, sizeof state);
for (int k = 0; k < n; k++) {
if (a[k][p] == a[k][p + 1]) {
int x = u.right[k];
int y = v.left[k] + 21;
while (state[x]) {
x = state[x];
}//路径压缩
while (state[y]) {
y = state[y];
}
if (x != y) {
f.cnt--;
state[y] = x;
}
}
}
int g = 1;
memset(mark, 0, sizeof mark);
for (int k = 0; k < n; k++) {
int x = u.left[k];
while (state[x]) {
x = state[x];
}
if (mark[x] == 0) {
mark[x] = g++;
}//从头标号 只需记录左边界和右边界
f.left[k] = mark[x];//重新标记边界
int y = v.right[k] + 21;
while (state[y]) {
y = state[y];
}
if (mark[y] == 0) {
mark[y] = g++;
}
f.right[k] = mark[y];//重新标记边界
}
return f;
} void build(int l, int r, int i) {
if (l == r) {
for (int k = 0; k < n; k++) {
if (k == 0 || a[k][l] != a[k - 1][l]) {
tr[i].left[k] = tr[i].right[k] = ++tr[i].cnt;
} else {
tr[i].left[k] = tr[i].right[k] = tr[i].left[k - 1];
}
}
} else {
int mid = (l + r) >> 1;
build(l, mid, i + i);
build(mid + 1, r, i + i + 1);
tr[i] = join(tr[i + i], tr[i + i + 1], mid);
}
/*
cout << " + " << l << " " << r << "\n";
for (int k = 0; k < n; k++) {
cout << tr[i].left[k] << " ";
}
cout << "\n";
for (int k = 0; k < n; k++) {
cout << tr[i].right[k] << " ";
}
cout << "\n";
*/
} void get(int l, int r, int x, int y, int i, Info &res) {
if (x <= l && r <= y) {
if (l == x) {
res = tr[i];
} else {
res = join(res, tr[i], l - 1);
}
} else {
int mid = (l + r) >> 1;
if (mid >= x) {
get(l, mid, x, y, i + i, res);
}
if (mid < y) {
get(mid + 1, r, x, y, i + i + 1, res);
}
}
} int main() {
scanf("%d %d %d", &n, &m, &q);
for (int i = 0; i < n; i++) {
for (int j = 1; j <= m; j++) {
scanf("%d", &a[i][j]);
}
}
build(1, m, 1);
Info res;
while (q--) {
int l, r;
scanf("%d %d", &l, &r);
get(1, m, l, r, 1, res);
printf("%d\n", res.cnt);
}
}

  

codeforces round 416 div2 补题 CF 811 A B C D E的更多相关文章

  1. codeforces round 422 div2 补题 CF 822 A-F

    A I'm bored with life 水题 #include<bits/stdc++.h> using namespace std; typedef long long int LL ...

  2. codeforces round 421 div2 补题 CF 820 A-E

    A Mister B and Book Reading  O(n)暴力即可 #include<bits/stdc++.h> using namespace std; typedef lon ...

  3. Codeforces round 419 div2 补题 CF 816 A-E

    A Karen and Morning 水题 注意进位即可 #include<bits/stdc++.h> using namespace std; typedef long long i ...

  4. codeforces round 418 div2 补题 CF 814 A-E

    A An abandoned sentiment from past 水题 #include<bits/stdc++.h> using namespace std; int a[300], ...

  5. codeforces round 417 div2 补题 CF 812 A-E

    A Sagheer and Crossroads 水题略过(然而被Hack了 以后要更加谨慎) #include<bits/stdc++.h> using namespace std; i ...

  6. codeforces round 420 div2 补题 CF 821 A-E

    A Okabe and Future Gadget Laboratory 暴力 #include<bits/stdc++.h> using namespace std; typedef l ...

  7. Educational Codeforces Round 23 A-F 补题

    A Treasure Hunt 注意负数和0的特殊处理.. 水题.. 然而又被Hack了 吗的智障 #include<bits/stdc++.h> using namespace std; ...

  8. codeforces 447 A-E div2 补题

    A DZY Loves Hash 水题 #include<iostream> #include<cstdio> #include<cstdlib> #include ...

  9. codeforces round #416 div2

    A:暴力模拟 #include<bits/stdc++.h> using namespace std; int a, b; int main() { scanf("%d%d&qu ...

随机推荐

  1. js 技巧 (二)

    //最小化,最大化,关闭 <object id=min classid="clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11">  & ...

  2. python 库文件版本收集及安装

    版本收集:pip freeze > require.txt版本安装:pip install -r require.txt

  3. Cropping multiple images the same way

    The tools we’ll be using are =GIMP= and =mogrify= (from the ImageMagick suite), so make sure that yo ...

  4. 程序包javax.servlet.http不存在

    在maven test项目时,出现错误: java:[7,26] 程序包javax.servlet.http不存在 原因:pom.xml中未引入javax.servlert-api相关的包 <d ...

  5. 解决idea创建ssm项目找不到mybatis的mapper的xml文件问题

    http://blog.csdn.net/v19freedom/article/details/69855302 后来上网搜了下,别人给出的答复 idea在build工程的时候 遇到maven项目 使 ...

  6. [luoguP2444] [POI2000]病毒(AC自动机 + dfs)

    传送门 先把所有串建一个AC自动机, 如果要找一个不包含任意一个串的串, 说明这个串一直在AC自动机上匹配但匹配不到, 也就是说,匹配时除去val值为1的点,除去fail指针指向val值为1的点,是否 ...

  7. 上传图片+生成缩略图 ashx代码

    html页面 <form action="Handlers/UploadImageHandler.ashx" method="post" enctype= ...

  8. [K/3Cloud] 单据新增、复制、新增行、复制行的过程

    整单复制:先执行CopyData(获得数据包),在执行AfterCreateNewData(可处理数据包),不会执行AfterCreateNewEntryRow 单据新增:先执行AfterCreate ...

  9. 选择器的使用(first-child和last-child选择器)

    <!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head><meta ...

  10. Linux系统备份还原工具1(DD)(应用实例)

    DD使用教程:http://www.cnblogs.com/EasonJim/p/7442223.html 以下实例没经过大量测试,可能在一些机器上不会有效. 一般围绕以下几点进行设置: 1.dd完后 ...