【NOI2014】起床困难综合症

按位贪心

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#define maxn 100010
using namespace std; int n, m;
int tp[maxn], v[maxn]; int getans(int final, int p){
for(int i = 1; i <= n; i ++){
if(tp[i] == 0)final &= v[i];
if(tp[i] == 1)final |= v[i];
if(tp[i] == 2)final ^= v[i];
}return final >> p & 1;
} bool check(int x){
if(getans(0, x) >= getans(1 << x, x))
return 0;
return 1;
} int solve(int final){
for(int i = 1; i <= n; i ++){
if(tp[i] == 0)final &= v[i];
if(tp[i] == 1)final |= v[i];
if(tp[i] == 2)final ^= v[i];
}return final;
} int main(){
scanf("%d%d", &n, &m);
char cmd[5]; int x;
for(int i = 1; i <= n; i ++){
scanf("%s%d", cmd, &x);
if(cmd[0] == 'A')tp[i] = 0;
if(cmd[0] == 'O')tp[i] = 1;
if(cmd[0] == 'X')tp[i] = 2;
v[i] = x;
}
int log = 1;
for(; 1ll << log <= m; log ++);log --;
int ans = 0;
for(int i = log; i >= 0; i --)
if((ans | (1 << i)) <= m && check(i))
ans = ans | (1 << i);
printf("%d\n", solve(ans));
return 0;
}

【NOI2014】魔法森林

最小增量生成树

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define maxn 200010
using namespace std; int n, m; struct Edge_{
int u, v, a, b;
void read(){scanf("%d%d%d%d", &u, &v, &a, &b);}
bool operator<(const Edge_& k)const{
return a < k.a;
}
}G[maxn]; int L[maxn], R[maxn];
int val[maxn], c[maxn][2], fa[maxn], pos[maxn];
bool rev[maxn]; namespace Splay{
#define l c[x][0]
#define r c[x][1]
int st[maxn], top;
void init(){
memset(val, 0x80, sizeof val);
for(int i = 1; i <= 2 * n; i ++)
pos[i] = i;
} void pushup(int x){
pos[x] = x;
if(val[pos[x]] < val[pos[l]])
pos[x] = pos[l];
if(val[pos[x]] < val[pos[r]])
pos[x] = pos[r];
} void pushdown(int x){
if(rev[x]){
rev[x] = 0;
rev[l] ^= 1;
rev[r] ^= 1;
swap(l, r);
}
} void rotate(int p, int x){
int mark = p == c[x][1], y = c[p][mark ^ 1];
int z = fa[x];
if(x == c[z][0])c[z][0] = p;
if(x == c[z][1])c[z][1] = p;
if(y)fa[y] = x;
fa[p] = z; c[p][mark ^ 1] = x;
fa[x] = p; c[x][mark] = y;
pushup(x);
} bool isroot(int p){
return c[fa[p]][0] != p && c[fa[p]][1] != p;
} void splay(int p){
st[top = 1] = p;
for(int i = p; !isroot(i); i = fa[i])
st[++ top] = fa[i];
for(;top; top --)
pushdown(st[top]); while(!isroot(p)){
int x = fa[p], y = fa[x];
if(isroot(x))rotate(p, x);
else if(p == c[x][0] ^ x == c[y][0])
rotate(p, x), rotate(p, y);
else rotate(x, y), rotate(p, x);
}
pushup(p);
}
#undef l
#undef r
} namespace LCT{
void Access(int u){
int t = 0;
while(u){
Splay::splay(u);
c[u][1] = t;
t = u;
u = fa[u];
}
} void Evert(int u){
Access(u);
Splay::splay(u);
rev[u] ^= 1;
} void link(int u, int v, int t){
Evert(v);
fa[v] = t;
Evert(t);
fa[t] = u;
} void cut(int u, int v, int t){
Evert(t);
Access(u);
Splay::splay(u);
c[u][0] = fa[t] = 0;
Evert(t);
Access(v);
Splay::splay(v);
c[v][0] = fa[t] = 0;
} int find(int u){
Access(u);
Splay::splay(u);
while(c[u][0])u = c[u][0];
return u;
} int ask(int u, int v){
if(find(u) != find(v))
return -1;
Evert(u);
Access(v);
Splay::splay(v);
return pos[v];
}
} int main(){
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i ++)
G[i].read();
sort(G + 1, G + 1 + m);
Splay::init();
int ans = 0x7fffffff;
int cnt = n;
for(int i = 1; i <= m; i ++){
int t = LCT::ask(G[i].u, G[i].v);
if(t == -1){
t = ++ cnt;
L[t] = G[i].u;
R[t] = G[i].v;
val[t] = G[i].b;
fa[t] = c[t][0] = c[t][1] = 0;
pos[t] = t;
LCT::link(L[t], R[t], t);
}
else if(val[t] > G[i].b){
LCT::cut(L[t], R[t], t);
L[t] = G[i].u;
R[t] = G[i].v;
val[t] = G[i].b;
fa[t] = c[t][0] = c[t][1] = 0;
pos[t] = t;
LCT::link(L[t], R[t], t);
}
t = LCT::ask(1, n);
if(t != -1)
ans = min(ans, val[t] + G[i].a);
//cout << ans << ' ' << val[t] << ' ' << G[i].a << ' ' << G[i].b << endl;
} if(ans > 1000000)
ans = -1;
printf("%d\n", ans); return 0;
}

【NOI2014】动物园

KMP

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 1000010
#define mod 1000000007ll
using namespace std; int nxt[maxn], n; char c[maxn]; int p[maxn]; long long ans;
void solve(){
p[1] = 1;
nxt[0] = nxt[1] = 0;
for(int i = 2; i <= n; i ++){
int j = nxt[i - 1];
while(j && c[i] != c[j + 1])j = nxt[j];
if(c[i] == c[j + 1])j ++;
nxt[i] = j;
p[i] = p[j] + 1;
} int j = 0;
ans = 1;
for(int i = 2; i <= n; i ++){
while(j && c[i] != c[j + 1])j = nxt[j];
if(c[i] == c[j + 1])j ++;
while(j * 2 > i)j = nxt[j];
ans = 1ll * (p[j] + 1) * ans % mod;
}
printf("%lld\n", ans);
} int main(){
int test;
scanf("%d", &test);
while(test --){
scanf("%s", c + 1);
n = strlen(c + 1);
solve();
}
return 0;
}

【NOI2014】随机数生成器

把序列搞出来每次取最小值看是否可以添加进去

每一行可取的范围是连续的,维护Li和Ri就可以判定

#include <algorithm>
#include <stdio.h>
typedef long long ll;
int x0, a, b, c, d;
int n, m, q;
int T[25000001], mp[5001][5001];
int l[5001], r[5001];
int Rand(){
x0 = ((ll)a * x0 * x0 % d + (ll)b * x0 + c) % d;
return x0;
} int main(){
scanf("%d%d%d%d%d", &x0, &a, &b, &c, &d);
scanf("%d%d%d", &n, &m, &q);
int k = n * m;
for(int i = 1; i <= k; i ++)
T[i] = i; for(int i = 1; i <= k; i ++)
std::swap(T[i], T[Rand() % i + 1]);
int x, y;
for(int i = 1; i <= q; i ++)
scanf("%d%d", &x, &y), std::swap(T[x], T[y]); int nw = 0;
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= m; j ++)
mp[i][j] = T[++ nw];
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= m; j ++)
T[mp[i][j]] = i << 16 | j;
for(int i = 1; i <= n; i ++)
l[i] = 1, r[i] = m;
bool flag = false;
for(int i = 1; i <= k; i ++){
x = T[i] >> 16;
y = T[i] & 65535;
if(l[x] <= y && y <= r[x]){
if(flag)putchar(' ');
flag = true;
printf("%d", i);
for(int j = 1; j < x; j ++)r[j] = std::min(r[j], y);
for(int j = x + 1; j <= n; j ++)l[j] = std::max(l[j], y);
}
}
return 0;
}

【NOI2014】购票

树剖+三分

long long 乘 long long乘爆了。。

改成double才过

凸包不要建错

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#define maxn 200010
using namespace std;
typedef long long ll;
int n;
struct Edge{
int to, nxt;
ll dis;
}edge[maxn]; int h[maxn], cnt;
void add(int u, int v, ll d){
edge[++ cnt] = (Edge){v, h[u], d};
h[u] = cnt;
} const ll inf = 1ll << 60;
const int root = 1;
ll p[maxn], q[maxn], L[maxn], dis[maxn], dp[maxn]; int fa[maxn], anc[maxn][20];
int top[maxn], son[maxn], pos[maxn], size[maxn], dfs_clock; void dfs1(int u){
size[u] = 1;
for(int i = h[u]; i; i = edge[i].nxt){
int v = edge[i].to;
if(v == fa[u])continue;
anc[v][0] = fa[v] = u;
dis[v] = dis[u] + edge[i].dis;
dfs1(v);
size[u] += size[v];
if(size[v] > size[son[u]])
son[u] = v;
}
} void dfs2(int u, int tp){
pos[u] = ++ dfs_clock;
top[u] = tp;
if(son[u])dfs2(son[u], tp);
for(int i = h[u]; i; i = edge[i].nxt){
int v = edge[i].to;
if(v == fa[u] || v == son[u])continue;
dfs2(v, v);
}
} int Find(int u, ll d){
for(int i = 18; i >= 0; i --)
if(dis[anc[u][i]] >= d)
u = anc[u][i];
return u;
} #define lc id << 1
#define rc id << 1 | 1
vector<int> t[maxn << 2]; void update(int id, int l, int r, int u){
int top = t[id].size() - 1;
while(top > 0){
int t1 = t[id][top], t2 = t[id][top - 1];
if((double)(dp[u] - dp[t1]) / (dis[u] - dis[t1]) < (double)(dp[u] - dp[t2]) / (dis[u] - dis[t2]))
top --, t[id].pop_back();
else break;
}
t[id].push_back(u);
if(l == r)return;
int mid = l + r >> 1;
if(pos[u] <= mid)update(lc, l, mid, u);
else update(rc, mid+1, r, u);
} ll pd(int i, int u){return dp[i] + (dis[u] - dis[i]) * p[u] + q[u];} ll check(int id, int u){
int l = 0, r = t[id].size() - 1;
ll ret = inf;
while(r - l >= 3){
int m1 = (l + l + r) / 3, m2 = (l + r + r) / 3;
if(pd(t[id][m1], u) > pd(t[id][m2], u))
l = m1;
else r = m2;
}
for(int i = l; i <= r; i ++)
ret = min(ret, pd(t[id][i], u));
return ret;
} ll ask(int id, int l, int r, int L, int R, int u){
if(l == L && r == R)return check(id, u);
int mid = l + r >> 1;
if(R <= mid)return ask(lc, l, mid, L, R, u);
if(L > mid) return ask(rc, mid+1, r, L, R, u);
return min(ask(lc, l, mid, L, mid, u), ask(rc, mid+1, r, mid+1, R, u));
} ll query(int u){
ll d = dis[u] - L[u], ret = inf;
int nw = u; u = fa[u];
while(u){
if(dis[u] < d)break;
int l = pos[top[u]], r = pos[u];
if(dis[top[u]] < d)l = pos[Find(u, d)];
ret = min(ret, ask(1, 1, n, l, r, nw));
u = fa[top[u]];
}return ret;
} void solve(int u){
if(u != 1)dp[u] = query(u);
update(1, 1, n, u);
for(int i = h[u]; i; i = edge[i].nxt){
int v = edge[i].to;
if(v == fa[u])continue;
solve(v);
}
} int main(){
int test;
scanf("%d%d", &n, &test);
int f; ll s;
for(int i = 2; i <= n; i ++){
scanf("%d%lld%lld%lld%lld", &f, &s, &p[i], &q[i], &L[i]);
add(f, i, s);
}
dfs1(root);
dfs2(root, root);
for(int j = 1; 1 << j <= n; j ++)
for(int i = 1; i <= n; i ++)
anc[i][j] = anc[anc[i][j-1]][j-1];
solve(root);
for(int i = 2; i <= n; i ++)
printf("%lld\n", dp[i]);
return 0;
}

  

[NOI 2014]做题记录的更多相关文章

  1. UOJ 做题记录

    UOJ 做题记录 其实我这么弱> >根本不会做题呢> > #21. [UR #1]缩进优化 其实想想还是一道非常丝播的题目呢> > 直接对于每个缩进长度统计一遍就好 ...

  2. project euler做题记录

    ProjectEuler_做题记录 简单记录一下. problem 441 The inverse summation of coprime couples 神仙题.考虑答案为: \[\begin{a ...

  3. Sam做题记录

    Sam做题记录 Hihocoder 后缀自动机二·重复旋律5 求一个串中本质不同的子串数 显然,答案是 \(\sum len[i]-len[fa[i]]\) Hihocoder 后缀自动机三·重复旋律 ...

  4. 退役IV次后做题记录

    退役IV次后做题记录 我啥都不会了.... AGC023 D 如果所有的楼房都在\(S\)同一边可以直接得出答案. 否则考虑最左最右两边的票数,如果左边>=右边,那么最右边会投给左边,因为就算车 ...

  5. 退役III次后做题记录(扯淡)

    退役III次后做题记录(扯淡) CF607E Cross Sum 计算几何屎题 直接二分一下,算出每条线的位置然后算 注意相对位置这个不能先搞出坐标,直接算角度就行了,不然会卡精度/px flag:计 ...

  6. 退役II次后做题记录

    退役II次后做题记录 感觉没啥好更的,咕. atcoder1219 历史研究 回滚莫队. [六省联考2017]组合数问题 我是傻逼 按照组合意义等价于\(nk\)个物品,选的物品\(\mod k\) ...

  7. BJOI做题记录

    BJOI做题记录 终于想起还要做一下历年省选题了2333 然而咕了的还是比做了的多2333 LOJ #2178. 「BJOI2017」机动训练 咕了. LOJ #2179. 「BJOI2017」树的难 ...

  8. FJOI2017前做题记录

    FJOI2017前做题记录 2017-04-15 [ZJOI2017] 树状数组 问题转化后,变成区间随机将一个数异或一,询问两个位置的值相等的概率.(注意特判询问有一个区间的左端点为1的情况,因为题 ...

  9. [日记&做题记录]-Noip2016提高组复赛 倒数十天

    写这篇博客的时候有点激动 为了让自己不颓 还是写写日记 存存模板 Nov.8 2016 今天早上买了两个蛋挞 吃了一个 然后就做数论(前天晚上还是想放弃数论 但是昨天被数论虐了 woc noip模拟赛 ...

随机推荐

  1. HDOJ 1026 dfs路径保存

    #include<cstdio> #include<cstring> #include<cmath> ][]; #define inf 0xffffff int n ...

  2. Spring事务传播、隔离等级

    事务传播 PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中.这是最常见的选择. PROPAGATION_SUPPORTS 支持当前事 ...

  3. ios7技巧:你需要掌握的19个iOS7使用技巧

    从右往左滑动屏幕,可看到信息收到的时间. 指南针应用还可以用作水平仪,滑动屏幕即可. 被苹果称作Spotlight的搜索功能有所改变.在屏幕中间向下滑动即可打开该项功能,你可以搜索文本.邮件.应用.歌 ...

  4. 20145221 《Java程序设计》实验报告二:Java面向对象程序设计

    20145221 <Java程序设计>实验报告二:Java面向对象程序设计 实验要求 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O. ...

  5. VS添加lib库

    #pragma comment(lib,"opengl32.lib")

  6. [MAC] SVN lock的使用

    转载 : http://www.eefocus.com/czzheng/blog/12-03/245532_4ca94.html 如果压根没有锁lock,那么每个人都拥有一个本地copy,每个人都能自 ...

  7. java类初始化优先级

    父类静态变量.父类静态代码块.子类静态变量.子类静态代码块.父类非静态变量.父类非静态代码块.父类构造函数.子类非静态变量.子类非静态代码块.子类构造函数

  8. Eclipse 代码格式化

    http://blog.csdn.net/prstaxy/article/details/7839197 http://jingyan.baidu.com/article/9158e00044efb6 ...

  9. repo的用法

    转自:http://blog.csdn.net/junglyfine/article/details/6299636 注:repo只是google用Python脚本写的调用Git的一个脚本,主要是用来 ...

  10. Android虚拟机中的sqlite数据库文件

    Android虚拟机中的sqlite数据库文件 ①