【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. codeforces 479C Exams 解题报告

    题目链接:http://codeforces.com/problemset/problem/479/C 题目意思:简单来说,就是有个人需要通过 n 门考试,每场考试他可以选择ai, bi 这其中一个时 ...

  2. [Android UI] shape和selector的结合使用

    shape和selector是Android UI设计中经常用到的,比如我们要自定义一个圆角Button,点击Button有些效果的变化,就要用到shape和selector.可以这样说,shape和 ...

  3. Windows下安装Cygwin及包管理器apt-cyg(转)

    本文为转载文章: http://www.2cto.com/os/201212/176551.html Cygwin可以在Windows下使用unix环境Bash和各种功能强大的工具,对于Linux管理 ...

  4. php 条件查询和多条件查询

    条件循环 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3 ...

  5. redis的单实例配置+web链接redis

    [root@cache01 src]# wget http://download.redis.io/redis-stable.tar.gz [root@cache01 src]# tar -xzvf ...

  6. grep' \b\b'

    \b单词锁定符,如: '\bgrep\b'只匹配grep [root@86 ttf-arphic-uming-0.0.20050501]# cat /proc/diskstats 1 0 ram0 0 ...

  7. SVN常见错误和版本冲突解决

    之前在Eclipse下面误删除了svn的一些插件包,后来重装了就问题重重,在这里还是建议, Windows下SVN最好使用桌面版,在文件管理器下面更新和提交. 1.常见错误整理 #, c-format ...

  8. Maven打包部署脚本

    #!/bin/sh SVN_USER_NAME= SVN_PASSWORD= ROOT_PATH PROJECT_NAME ACTION SVN_LIB_ROOT USER_ACCOUNT PASSW ...

  9. Java Hour 26 Execution

    有句名言,叫做10000小时成为某一个领域的专家.姑且不辩论这句话是否正确,让我们到达10000小时的时候再回头来看吧. 26 Hours. Java 虚拟机启动的时候加载一个指定的类然后调用该类中的 ...

  10. vijos 1037 ***

    链接:点我 #include <cstdio> #include <cstring> #include <algorithm> #include <iostr ...