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. Oracle诊断:drop table失败[转]

    转: From <http://blog.csdn.net/cyxlxp8411/article/details/7775113> 今天在drop一张表的时候报ORA-00054错误 SQ ...

  2. 移动Anaconda安装目录后导致图标变白以及Anaconda Navigator,Anaconda Prompt,jupyter notebook和spyder启动不了的解决方法

    Q:因为移动了Anaconda3的安装目录,所以Anaconda3的相应应用程序启动不了,包括图标也会变白 解决方法:修改对应快捷键的属性,有对应的启动位置,修改下位置路径配置以及图标(Anacond ...

  3. Git-Runoob:Git 教程

    ylbtech-Git-Runoob:Git 教程 1.返回顶部 1. Git 教程 Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. Git 是 Linus Torva ...

  4. OpenStack Rally 质量评估与自动化测试利器

    目录 文章目录 目录 问题描述 Rally 简介 应用场景 应用案例 Rally 安装 Rally 使用 Rally 架构 Rally Plugin 分析与实现 程序入口 执行 rally task ...

  5. Android下Native的so编译:使用cmakelists.txt

    android studio的CMakeLists.txt写好后,在Studio中编译没问题,在命令编译时则需要配置很多参数才能成功 示例CMakeLists.txt文件: cmake_minimum ...

  6. FreeMarker开发-数据模型

    FreeMarker用于处理模板的数据模型是哈希表,也就是一个树状结构的name-value对.如下: (root)|+- string="string"| +- map| || ...

  7. Java ——扩展:内部类 匿名内部类 IO file 设计模式

    内部类的拓展 定义类or方法内部的类 最外层的类只能使用public和默认修饰 class Demo { class A { } public static void main(String[] ar ...

  8. C++——堆、栈与内存管理

    简介 Stack,是存在于某作用域(scope) 的一块内存空间(memory space).例如当你调用函数,函数本身即会形成一个stack 用來放置它所接收的参数,以及返回地址.在函数本体(fun ...

  9. java8-----lambda语法

    // -----lambda语法1------ https://www.baidu.com/link?url=6iszXQlsmyaoWVZMaPs3g8vLRQXzdzTnKzQYTF8lg-5QQ ...

  10. 剑指Offer编程题(Java实现)——反转链表

    题目描述 输入一个链表,反转链表后,输出新链表的表头. 思路一 使用头插法迭代进行反转 实现 /* public class ListNode { int val; ListNode next = n ...