codeforces round 416 div2 补题 CF 811 A B C D E
水题略过
- #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;
- }
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]);
- }
第一步判断一下按钮是否反转即可。剩下的直接暴力求路径,水题。
- #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的更多相关文章
- 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 ...
- 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 ...
- Codeforces round 419 div2 补题 CF 816 A-E
A Karen and Morning 水题 注意进位即可 #include<bits/stdc++.h> using namespace std; typedef long long i ...
- codeforces round 418 div2 补题 CF 814 A-E
A An abandoned sentiment from past 水题 #include<bits/stdc++.h> using namespace std; int a[300], ...
- codeforces round 417 div2 补题 CF 812 A-E
A Sagheer and Crossroads 水题略过(然而被Hack了 以后要更加谨慎) #include<bits/stdc++.h> using namespace std; i ...
- codeforces round 420 div2 补题 CF 821 A-E
A Okabe and Future Gadget Laboratory 暴力 #include<bits/stdc++.h> using namespace std; typedef l ...
- Educational Codeforces Round 23 A-F 补题
A Treasure Hunt 注意负数和0的特殊处理.. 水题.. 然而又被Hack了 吗的智障 #include<bits/stdc++.h> using namespace std; ...
- codeforces 447 A-E div2 补题
A DZY Loves Hash 水题 #include<iostream> #include<cstdio> #include<cstdlib> #include ...
- codeforces round #416 div2
A:暴力模拟 #include<bits/stdc++.h> using namespace std; int a, b; int main() { scanf("%d%d&qu ...
随机推荐
- Matlab学习笔记(四)
二.MATLAB基础知识 (六)字符串 字符串的创建和简单操作 用单引号对括起来的一系列字符的组合,每个字符是一个元素,通常通过两个字节来存储 表2-22 字符串常见操作函数(e_two_37. ...
- 【Codeforces 444A】DZY Loves Physics
[链接] 我是链接,点我呀:) [题意] 题意 [题解] 两个点的子图他们的"密度"是比所有联通生成子图都要大的 "只要胆子大,遇到什么问题都不怕!" [代码] ...
- 587. Erect the Fence
Problem statement: There are some trees, where each tree is represented by (x,y) coordinate in a two ...
- TensorFlow-GPU环境配置之一——安装Ubuntu双系统
本机已经安装过Windows系统,准备安装Ubuntu双系统进行TensorFlow相关工作,需要在windows中将磁盘分出一定空间供Ubuntu使用 1.首先下载Ubuntu17.04版本ISO ...
- pymongo collection.save 问题
项目中有这样一个需求,把路由器信息存入mongo,DB的结构如下: { router_name: name, router_ip: ip, interfaces: [ {oid:1,name:if1} ...
- Rust 1.7.0 macro宏的复用 #[macro_use]的使用方法
Rust 1.7.0 中的宏使用范围包含三种情况: 第一种情况是宏定义在当前文件里.这个文件可能是 crate 默认的 module,也可能是随意的 module 模块. 另外一种情况是宏定义在当前 ...
- android动态控制组件的位置、大小和新的动画
一.动态设置组件的位置 当中view是须要改变位置的控件,top是须要设制的位置: private static void setLayoutX(View view,int top) { //克隆v ...
- boost::mpl::eval_if的使用方法
近期看boost的时候总是遇见这个eval_if,不知道啥意思,就没法看下去了,比方 前篇文章boost::serialization 拆分serialize函数分析时就出现这样一段代码: templ ...
- 公用表表达式(CTE)
公用表表达式(CTE,Common table expression)是和派生表很相似的另一种形式的表表达式,而且具有一些重要优势.CTE 是在 SQL Server 2005 中引入的,是ANSI ...
- 打开google 新地址
还在为谷歌打不开而发愁吗? 那就试试这个吧 91.213.30.151