A

#include <bits/stdc++.h>
#define PI acos(-1.0)
#define mem(a,b) memset((a),b,sizeof(a))
#define TS printf("!!!\n")
#define pb push_back
#define inf 0x3f3f3f3f
//std::ios::sync_with_stdio(false);
using namespace std;
//priority_queue<int,vector<int>,greater<int>> que; get min
const double eps = 1.0e-10;
const double EPS = 1.0e-4;
typedef pair<int, int> pairint;
typedef long long ll;
typedef unsigned long long ull;
//const int maxn = 3e5 + 10;
const int turn[][] = {{, }, { , }, { , -}, { -, }};
//priority_queue<int, vector<int>, less<int>> que;
//next_permutation
int main()
{
string f;
cin >> f;
int len = f.size();
int flag = ;
int numa = ;
int numb = ;
int numc = ;
int now = ;
for (int i = ; i < len; i++)
{
if (f[i] - 'a' < now)
{
flag = ;
break;
}
else
{
now = max(now, f[i] - 'a');
}
}
if (!flag)
{
cout << "NO" << endl;
return ;
}
for (int i = ; i < len; i++)
{
if (f[i] == 'a')
{
numa++;
}
else if (f[i] == 'b')
{
numb++;
}
else
{
numc++;
}
}
if (numa < || numb < )
{
cout << "NO" << endl;
return ;
}
if (numc == numa || numc == numb)
{
cout << "YES" << endl;
}
else
{
cout << "NO" << endl;
}
}

B

#include <bits/stdc++.h>
#define PI acos(-1.0)
#define mem(a,b) memset((a),b,sizeof(a))
#define TS printf("!!!\n")
#define pb push_back
#define inf 0x3f3f3f3f
//std::ios::sync_with_stdio(false);
using namespace std;
//priority_queue<int,vector<int>,greater<int>> que; get min
const double eps = 1.0e-10;
const double EPS = 1.0e-4;
typedef pair<int, int> pairint;
typedef long long ll;
typedef unsigned long long ull;
//const int maxn = 3e5 + 10;
const int turn[][] = {{, }, { , }, { , -}, { -, }};
//priority_queue<int, vector<int>, less<int>> que;
//next_permutation
priority_queue<ll, vector<ll>, less<ll>> que;
ll a[];
ll b[];
int main()
{
ll anser = ;
ll n, k1, k2;
cin >> n >> k1 >> k2;
for (int i = ; i <= n; i++)
{
scanf("%lld", &a[i]);
}
for (int i = ; i <= n; i++)
{
scanf("%lld", &b[i]);
que.push(abs(a[i] - b[i]));
anser += abs(a[i] - b[i]) * abs(a[i] - b[i]);
}
int cur = k1 + k2;
while (cur)
{
ll now = que.top();
que.pop();
if (now == )
{
cur--;
que.push();
anser += ;
}
else
{
cur--;
que.push(now - );
anser -= 1LL * now * now;
anser += 1LL * (now - ) * (now - );
}
}
cout << anser << endl;
}

C

#include <bits/stdc++.h>
#define PI acos(-1.0)
#define mem(a,b) memset((a),b,sizeof(a))
#define TS printf("!!!\n")
#define pb push_back
#define inf 0x3f3f3f3f
//std::ios::sync_with_stdio(false);
using namespace std;
//priority_queue<int,vector<int>,greater<int>> que; get min
const double eps = 1.0e-10;
const double EPS = 1.0e-4;
typedef pair<int, int> pairint;
typedef long long ll;
typedef unsigned long long ull;
//const int maxn = 3e5 + 10;
const int turn[][] = {{, }, { , }, { , -}, { -, }};
//priority_queue<int, vector<int>, less<int>> que;
//next_permutation
priority_queue<ll, vector<ll>, less<ll>> que;
vector<ll> ans;
int main()
{
//freopen("out.txt","w",stdout);
ll x, d;
cin >> x >> d;
// if(x<=10000)
// {
// for(ll i=1;x;i+=d+1)
// {
// cout<<i<<" ";
// x--;
// }
// return 0;
// }
ll cur = ;
if (x == )
{
cout << << endl;
cout << << endl;
return ;
}
if (x & )
{
ans.push_back(1e17 - );
x -= ;
}
for (ll i = ; i <= ; i++)
{
if ((1LL << i)&x)
{
que.push(i);
}
}
while (!que.empty())
{
ll number = que.top();
que.pop();
for (ll i = ; i <= number; i++)
{
ans.push_back(cur);
}
cur += d;
ans.push_back(cur);
cur += d;
}
cout << ans.size() << endl;
for (ll ch : ans)
{
cout << ch << " ";
}
}

D

给你一个完全二叉树有三种操作

1.把值为X的节点所在当前层 移动K次

2.把值为X的节点所在当前层 移动K次 子树也跟着移动

3.询问你值为X所在结点到根节点路径上节点的值

shift[i]表示第i层移动的次数

第二个操作很好处理 第三个操作就是在第二个操作上pushdown 下一层移动的次数是上一层的两倍

(记得取模操作)

#include <bits/stdc++.h>
#define PI acos(-1.0)
#define mem(a,b) memset((a),b,sizeof(a))
#define TS printf("!!!\n")
#define pb push_back
#define inf 0x3f3f3f3f
//std::ios::sync_with_stdio(false);
using namespace std;
//priority_queue<int,vector<int>,greater<int>> que; get min
const double eps = 1.0e-10;
const double EPS = 1.0e-4;
typedef pair<int, int> pairint;
typedef long long ll;
typedef unsigned long long ull;
//const int maxn = 3e5 + 10;
const int turn[][] = {{, }, { , }, { , -}, { -, }};
//priority_queue<int, vector<int>, less<int>> que;
//next_permutation
int Q;
int T;
ll level;
ll X, K;
ll lenth, position;
ll shift[];
void update(ll x, ll K)
{
shift[x] += K;
shift[x] %= (1LL << (x - ));
}
void pushdown(ll x, ll K)
{
shift[x] += K;
shift[x] %= (1LL << (x - ));
if (x + < )
{
K = (K << );
pushdown(x + , K);
}
}
ll getpos(ll level, ll x)
{
ll l = 1LL << (level - );
ll r = (1LL << level) - ;
ll now = x + shift[level];
if (l <= now && now <= r)
{
return now;
}
if (now < l)
{
ll cha = l - now - ;
return r - cha;
}
else
{
ll cha = now - r - ;
return l + cha;
}
}
void print(ll level, ll pos)
{
if (level == )
{
cout << ;
return ;
}
ll now = pos - shift[level];
ll l = 1LL << (level - );
ll r = (1LL << level) - ;
if (l <= now && now <= r)
{
cout << now << " ";
print(level - , pos / );
return;
}
if (now < l)
{
ll cha = l - now - ;
cout << r - cha << " ";
}
else
{
ll cha = now - r - ;
cout << l + cha << " ";
}
print(level - , pos / );
return ;
}
int main()
{
//freopen("out.txt","w",stdout);
cin >> Q;
while (Q--)
{
int T;
scanf("%d %lld", &T, &X);
for (ll i = ; i >= ; i--)
{
if ((1LL << (i - ))&X)
{
if (((1LL << i)&X) == )
{
level = i;
break;
} }
}
//cout<<level<<" ";
if (T == )
{
scanf("%lld", &K);
if (X == )
{
continue;
}
K %= 1LL << (level - );
update(level, K);
}
else if (T == )
{
scanf("%lld", &K);
if (X == )
{
continue;
}
K %= 1LL << (level - );
pushdown(level, K);
}
else
{
if (X == )
{
cout << << endl;
continue;
}
cout << X << " ";
position = getpos(level, X);
//cout << position;
print(level - , position / );
cout << endl;
}
}
}

E

F

先来做F的简化版

http://codeforces.com/contest/459/problem/E

求有向图的最长严格递增路径

dp[i]表示以第i条边为结尾的最长路径 g[i]表示以i结点为结尾的最长路径

所以dp[i]=dp[edge[i].from]+1即以第i条边结尾的答案是以该边from结尾的最长路径长度+其本身

首先排序 相同大小的边之间是不会相连的

而如果每遍历一条边就g[edge[i].to]=max(g[edge[i].to],dp[i])的话 如果edge[i+1].from=edge[i].to 就变成这两条边相连了所以相同值的边要分处理

复杂度NLOGN

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define MAX 300007
using namespace std;
int n, m;
int dp[MAX], g[MAX];
struct Edge
{
int u, v, w;
bool operator < ( const Edge& a ) const
{
return w < a.w;
}
} e[MAX];
int main ( )
{
while ( ~scanf ( "%d%d" , &n , &m ) )
{
for ( int i = ; i < m ; i++ )
{
scanf ( "%d%d%d" , &e[i].u , &e[i].v , &e[i].w );
}
sort ( e , e + m );// 排序
int t = ;
e[m].w = -;//使得最后一组边也能更新
int ans = ; //答案
for ( int i = ; i < m ; i++ ) //从小到大枚举
{
int v = e[i].v;
int u = e[i].u;
int w = e[i].w;
dp[i] = g[e[i].u] + ; //以第i条边结尾的答案是以e[i].from节点为结尾的最长路径+它本身
if ( e[i].w != e[i + ].w )
{
for ( int j = t ; j <= i ; j++ ) //处理相同边
{
g[e[j].v] = max ( g[e[j].v] , dp[j] );//更新e[i].to的答案 以便处理下一组边
}
t = i + ;//重置相同边的起点
}
ans = max ( ans , dp[i] );
}
printf ( "%d\n" , ans );
}
}

现在来做F

如果用上面的方法来做 不能保证下标不能有逆序对这个条件

如果去掉edge[i].from=edge[j].to这个条件的话 这道题就变成一道裸的LIS

如果用来DP的话 普通的dp[i][j]数组表示以i为结尾的权重最大为j的最长递增路径长度 因为i和j都是1e5的会炸

但是用MAP来存的话 因为每个dp[i]表示的都是一个树状数组 每次插入和询问都是LOGN的 所以最多只会涉及到NLOGN个节点 可以接受

#include <bits/stdc++.h>
#define PI acos(-1.0)
#define mem(a,b) memset((a),b,sizeof(a))
#define TS printf("!!!\n")
#define pb push_back
#define inf 0x3f3f3f3f
//std::ios::sync_with_stdio(false);
using namespace std;
//priority_queue<int,vector<int>,greater<int>> que; get min
const double eps = 1.0e-10;
const double EPS = 1.0e-4;
typedef pair<int, int> pairint;
typedef long long ll;
typedef unsigned long long ull;
//const int maxn = 3e5 + 10;
const int turn[][] = {{, }, { , }, { , -}, { -, }};
//priority_queue<int, vector<int>, less<int>> que;
//next_permutation
const int N = 1e5 + ;
map<int, int> bits[N];
int query(int u, int x)
{
int ans = ;
while (x)
{
ans = max(ans, bits[u][x]);
x -= x & -x;
}
return ans;
}
void update(int u, int x, int v)
{
while (x < N)
{
bits[u][x] = max(bits[u][x], v);
x += x & -x;
}
}
int main()
{
int n, m, u, v, w;
int anser = ;
int cur;
scanf("%d%d", &n, &m);
for (int i = ; i < m; i++)
{
scanf("%d%d%d", &u, &v, &w);
w++;
cur = query(u, w - ) + ;
update(v, w, cur);
anser = max(anser, cur);
}
printf("%d\n", anser);
return ;
}

用主席树来做的话 其实和MAP DP递推是同理的 只建立需要的节点 其他节点忽略

#include<cstdio>
#include<algorithm>
#define lowbit(x) (x&-x)
using namespace std;
const int maxn=;
int n,m,f[maxn],rt[maxn],sz;
struct tree{int l,r,mx;}t[maxn*];
void insert(int& k,int l,int r,int x,int y){
if(!k)k=++sz;t[k].mx=max(t[k].mx,y);
if(l==r)return;
int mid=(l+r)>>;
if(x<=mid)insert(t[k].l,l,mid,x,y);
else insert(t[k].r,mid+,r,x,y);
}
int query(int k,int l,int r,int x){
if(l==r)return t[k].mx;
int mid=(l+r)>>;
if(x<=mid)return query(t[k].l,l,mid,x);
else return max(t[t[k].l].mx,query(t[k].r,mid+,r,x));
}
int main(){
scanf("%d%d",&n,&m);
int ans=;
for(int i=;i<=m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
f[i]=query(rt[u],,,w-)+;
insert(rt[v],,,w,f[i]);
ans=max(ans,f[i]);
}
printf("%d",ans);
return ; }

Codeforces 960 二进制构造子序列 完全二叉树shift模拟 主席树/MAP DP的更多相关文章

  1. CodeForces 464E The Classic Problem | 呆克斯歘 主席树维护高精度

    题意描述 有一个\(n\)点\(m\)边的无向图,第\(i\)条边的边权是\(2^{a_i}\).求点\(s\)到点\(t\)的最短路长度(对\(10^9 + 7\)取模). 题解 思路很简单--用主 ...

  2. CodeForces 294B Shaass and Bookshelf 【规律 & 模拟】或【Dp】

    这道题目的意思就是排两排书,下面这排只能竖着放,上面这排可以平着放,使得宽度最小 根据题意可以得出一个结论,放上这排书的Width 肯定会遵照从小到大的顺序放上去的 Because the total ...

  3. Codeforces 622C Not Equal on a Segment 【线段树 Or DP】

    题目链接: http://codeforces.com/problemset/problem/622/C 题意: 给定序列,若干查询,每个查询给定区间和t,输出区间内任意一个不等于t的元素的位置. 分 ...

  4. Codeforces Round #426 (Div. 2) D. The Bakery 线段树优化DP

    D. The Bakery   Some time ago Slastyona the Sweetmaid decided to open her own bakery! She bought req ...

  5. 4.13 省选模拟赛 树 树形dp 卷积 NTT优化dp.

    考试的时候 看到概率 看到期望我就怂 推了一波矩阵树推自闭了 发现 边权点权的什么也不是. 想到了树形dp 维护所有边的断开情况 然后发现数联通块的和再k次方过于困难. 这个时候 应该仔细观察一下 和 ...

  6. bzoj2989&&4170数列——二进制分组+主席树

    题意的转化挺巧妙的 可以联想到曼哈顿距离! 并且,所谓的修改还要查询历史版本,并且修改之间不动只算一次,不就是给平面上加一个点吗? 看成(x,a[x])的点 就是一个菱形区域 转切比雪夫距离,变成矩形 ...

  7. codeforces 1041 e 构造

    Codeforces 1041 E 构造题. 给出一种操作,对于一棵树,去掉它的一条边.那么这颗树被分成两个部分,两个部分的分别的最大值就是这次操作的答案. 现在给出一棵树所有操作的结果,问能不能构造 ...

  8. Tree Constructing CodeForces - 1003E(构造)

    题意: 就是让构造一个直径为d的树  每个结点的度数不能超过k 解析: 先构造出一条直径为d的树枝 然后去遍历这条树枝上的每个点  为每个点在不超过度数和直径的条件下添加子嗣即可 #include & ...

  9. Codeforces Round #271 (Div. 2) E题 Pillars(线段树维护DP)

    题目地址:http://codeforces.com/contest/474/problem/E 第一次遇到这样的用线段树来维护DP的题目.ASC中也遇到过,当时也非常自然的想到了线段树维护DP,可是 ...

随机推荐

  1. 快速排序和二分查找(Javascript)

    var data = [8, 3, 4, 1, 18, 22, 11, 3, 5, 6, 2, 1, 77] quickSort(data, 0, data.length - 1) console.l ...

  2. HTTP请求方式之POST和GET的区别

    GET请求方式: 如果我们的网页收集到的用户数据,他规定了,此网页用户数据用GET的请求方式去处理的话,我们会发现,比如百度,就是一个很经典的GET请求方式 当我们在百度搜索上输入一个‘java’,点 ...

  3. 使用tushare获取股票实时分笔数据延时有多大

    使用tushare获取股票实时分笔数据延时有多大 前几天分享了一段获取所有股票实时数据的代码,有用户积极留言,提出一个非常棒的问题:如果数据本生的延时非常严重,通过代码获取数据再快又有什么用呢? 一直 ...

  4. leetcode-mid- 50. Pow(x,n)-NO

    mycode  time limited 例如 x=0.00001 n=2147483647 参考: class Solution(object): def myPow(self, x, n): &q ...

  5. 1、Shiro简介以及整体架构

    1.Shiro概念和作用: 利用shiro可以快速完成权限管理模块的开发 Spring的官网也是用Shiro做安全管理的... Shiro整体架构: 可能你感觉上面的图片很乱,但是你一定要先大体有个印 ...

  6. .NET中使用EF6与连接MYSQL

    ADO.NET Entity Framework 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapping) 解决方案,不仅支持SQL Server,还支持MySQL.Ora ...

  7. C# DES 加解密

    using System; using System.Text; using System.Security.Cryptography; using System.Diagnostics; using ...

  8. excel 导入导出测试点

    目前,为方便操作,很多系统都会增加批量导入导出的功能.文件导入导出一般格式都是excel.由于用户直接在excel在填写内容,无法控制填写的格 式,加上excel解析比较困难,所以一般涉及到excel ...

  9. 修改jupyter notebook默认路径,亲测

    anaconda环境 任务栏中找到anaconda/jupyter notebook,鼠标右键属性 点击确认即可.

  10. 【Qt开发】Qt中显示图像的两种方法对比

    在Qt中处理图片一般都要用到QImage类,但是QImage的对象不能够直接显示出来,要想能看到图片,初步发现有两种方法. 一.QImage转QPixmap,然后用QLabel::setPixmap( ...