NOI2014
听说14,15年的题是最简单的,然后除了提答以外的不那么水的题都是以前讲过、做过的,都比较好想到,但是我实现起来却有各种Bug,也完全不能在5h里AC。。。太弱了
纯粹的送分题,每一位分开枚举选1和选0的答案,一样就选0,否则能选就选答案大的,不能就选0.
然后我脑残把返回((a[i]&(1LL<<j))>0)写成了返回(a[i]&(1LL<<j))wa了一发。。
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
const int N=1e5+;
typedef long long LL;
typedef double db;
using namespace std;
int n,m,a[N],power[];
char o[N][]; template<typename T> void read(T &x) {
char ch=getchar(); x=; T f=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} int calc(int pos,int v) {
For(i,,n) {
int w=(a[i]&power[pos])?:;
if(o[i][]=='A') v&=w;
if(o[i][]=='O') v|=w;
if(o[i][]=='X') v^=w;
}
return v;
} //#define DEBUG
int main() {
#ifdef DEBUG
freopen("1.in","r",stdin);
//freopen(".out","w",stdout);
#endif
read(n); read(m);
power[]=;
For(i,,) power[i]=(power[i-]<<);
For(i,,n) {
scanf("%s",o[i]);
read(a[i]);
}
int now=,ans=;
Rep(i,,) {
if(now+power[i]>m) {
int x=calc(i,);
if(x) ans+=power[i];
continue;
}
int rs1=calc(i,),rs2=calc(i,);
if(rs1==rs2) ans+=rs1*power[i];
else if(rs1>rs2) ans+=power[i];
else {
ans+=power[i];
now+=power[i];
}
}
printf("%d\n",ans);
return ;
}
听讲和讲过多次的题了。
这题我不会啊。。我可以手算第一个点。。
据说标解是什么拆成12*12的格子然后咋个搞一下。。
随便看了看觉得是水题,就不小心费了一个多小时
先没用脑袋写了一些什么kmp的假算法,随便就×掉,然后一直没想清楚。
然后想了下SA可以搞。但是看看数据是O(N)的啊。
又重新想kmp,一道水题想这么久,真是被自己蠢哭了。
求一个kmp的nxt数组,然后一个cnt数组表示从这一位沿着nxt跳包括自己在内可以跳多少步,pr数组表示沿着nxt跳到的第一个前后缀不重合的地方,那么答案就是num[x]=cnt[pr[x]-1]
如果nxt前后缀不重合则pr=nxt否则pr从pr[i-1]开始找即可。
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
const int N=,mod=1e9+;
typedef long long LL;
typedef double db;
using namespace std;
int T,n;
char s[N]; template<typename T> void read(T &x) {
char ch=getchar(); x=; T f=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} LL sum;
int nxt[N],pr[N],num[N],cnt[N];
void make_nxt() {
int k=;
For(i,,n-) num[i]=,cnt[i]=,pr[i]=;
For(i,,n-) {
while(k&&s[i]!=s[k]) k=nxt[k-];
if(s[i]==s[k]) k++;
nxt[i]=k;
pr[i]=k;
if(k) cnt[i]+=cnt[k-];
if(pr[i]&&pr[i]*>i+) {
pr[i]=pr[i-];
if(pr[i-]*==i) pr[i]=nxt[pr[i]-];
while(pr[i]&&s[pr[i]]!=s[i]) pr[i]=nxt[pr[i]-];
if(s[pr[i]]==s[i]) pr[i]++;
}
//int kk=k;
//while(kk&&kk*2>i+1) kk=nxt[kk-1];
if(pr[i]) num[i]+=cnt[pr[i]-];
}
} //#define DEBUG
int main() {
#ifdef DEBUG
freopen("1.in","r",stdin);
//freopen(".out","w",stdout);
#endif
read(T);
while(T--) {
scanf("%s",s);
n=strlen(s);
sum=;
make_nxt();
For(i,,n-) sum=sum*(num[i]+)%mod;
printf("%lld\n",sum);
}
return ;
}
第一反应是树套树,差点都开始打了发现我是个大sb……
容易发现贪心策略,每次从当前可以选的位置(若干个角相连的矩形)中选最大的一个,然后它所在的矩形就会被它分成两个。
可以用set维护这些矩形,开个数组维护每个位置还能不能选,然后从小往大选,每次选后把新不能选的部分标记
然后有点卡常
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define For(i,a,b) for(register int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(register int i=(a);i>=(b);i--)
#define FormyLove return 0
const int N=*+;
typedef long long LL;
typedef double db;
using namespace std;
LL x,a,b,c,d;
int T[N],tid[N],n,m,q,ans[N];
bool ok[N]; template<typename T> void read(T &x) {
char ch=getchar(); x=; T f=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} struct node {
int lx,ly,rx,ry;
node(int lx,int ly,int rx,int ry):lx(lx),ly(ly),rx(rx),ry(ry){}
friend bool operator <(const node &A,const node&B) {
return A.rx<B.rx;
}
};
set<node>s;
inline int get_x(int y) { return y%m?y/m+:y/m; }
inline int get_y(int y) { return y%m==?m:y%m; }
inline int get_id(int x,int y) { return (x-)*m+y; }
inline int in(node a,int xx,int yy) { return xx>=a.lx&&xx<=a.rx&&yy>=a.ly&&yy<=a.ry; } //#define DEBUG
int main() {
#ifdef DEBUG
freopen("1.in","r",stdin);
//freopen(".out","w",stdout);
#endif
read(tid[]); read(a); read(b); read(c); read(d);
read(n); read(m); read(q);
For(i,,n*m) T[i]=i;
For(i,,n*m) tid[i]=((LL)a*tid[i-]%d*tid[i-]%d+b*tid[i-]%d+c)%d;
For(i,,n*m) {
swap(T[i],T[tid[i]%i+]);
}
For(i,,q) {
int u,v;
read(u); read(v);
swap(T[u],T[v]);
}
For(i,,n*m) {
tid[T[i]]=i;
ok[i]=;
}
s.insert(node(,,n,m));
For(i,,n*m) if(ok[tid[i]]) {
ans[++ans[]]=i;
ok[tid[i]]=;
int xx=get_x(tid[i]),yy=get_y(tid[i]);
node t1=*s.lower_bound(node(xx,yy,xx,yy));
if(!in(t1,xx,yy)) t1=*++s.lower_bound(node(xx,yy,xx,yy));
if((xx==t1.lx&&yy==t1.ly)||(xx==t1.rx&&yy==t1.ry));
else {
s.erase(t1);
node t2=t1,t3=t1;
For(j,t1.lx,xx-) For(k,yy+,t1.ry) ok[get_id(j,k)]=;
For(j,xx+,t1.rx) For(k,t1.ly,yy-) ok[get_id(j,k)]=;
t2.rx=xx; t2.ry=yy; t3.lx=xx; t3.ly=yy;
if(t2.lx==t2.rx||t2.ly==t2.ry) {
For(i,t2.lx,t2.rx) For(j,t2.ly,t2.ry) {
int id=get_id(i,j);
if(ok[id]) ok[id]=,ans[++ans[]]=T[id];
}
}
else s.insert(t2);
if(t3.lx==t3.rx||t3.ly==t3.ry) {
For(i,t3.lx,t3.rx) For(j,t3.ly,t3.ry) {
int id=get_id(i,j);
if(ok[id]) ok[id]=,ans[++ans[]]=T[id];
}
}
else s.insert(t3);
}
}
sort(ans+,ans+ans[]+);
//unique(ans+1,ans+ans[0]+1);
For(i,,n+m-) printf("%d ",ans[i]); puts("");
FormyLove;
}
之前轩神讲过,刚好最近想找这道题,结果它自己找上门了。
F[x]=min(a[x]*(R[x]-R[y])+f[y]);
经过平面上一点(R[y],f[y])斜率为a[i]的直线的纵截距a[x]*R[y]+f[y]
那么可以对每个点从它到它上面能拓展到的最远点维护一个右下凸壳
维护的凸壳要支持删除和添加
回滚莫队+set似乎可以做到sqrt(n)logn,
如果用线段树呢
然后因为两个智障错误使我de了一整个晚上的bug
一是应该是一个区间满后建它前一个区间,而不是看一个区间后一个满没满再建它自己。。这样根本啥都没建,比暴力还慢
二是我建凸包的时候把while写成了for。。。
一整个晚上就没有了
唯一让我欣慰的是我发现有一位仁兄和我同时在做这道题,也做了一晚上,刷了一整版的提交记录,然后我们在相邻的两分钟内A了它
大概就是“同是天涯沦落人,相逢何必曾相识”吧
虽然这位大佬好像比我强很多很多很多
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
const int N=4e5+;
typedef long long LL;
typedef double db;
using namespace std;
int n,t,fa[N],sta[N],top;
LL f[N],R[N],lim[N],a[N],b[N]; template<typename T> void read(T &x) {
char ch=getchar(); x=; T f=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} int ecnt,fir[N],nxt[N],to[N];
LL val[N];
void add(int u,int v,LL w) {
nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w;
} #define lc x<<1
#define rc ((x<<1)|1)
#define mid ((l+r)>>1)
int ok[N<<],full[N<<],emp[N<<],tp[N],qr;
vector<int>ham[N<<]; #define LD long double
#define eps 1e-7
LD cross(int a1,int a2,int b1,int b2) { return (LD)(R[a1]-R[a2])*(f[b1]-f[b2])-(LD)(R[b1]-R[b2])*(f[a1]-f[a2]); } void get_ham(int x,int l,int r) {
qr=;
if(x==) {
int debug=;
}
For(i,l,r) {
while(qr>&&cross(sta[i],tp[qr-],tp[qr],tp[qr-])>-eps) qr--;
tp[++qr]=sta[i];
}
ham[x].clear();
For(i,,qr) ham[x].push_back(tp[i]);
ok[x]=;
} int xl[N<<],xr[N<<];
void build(int x,int l,int r) {
xl[x]=l; xr[x]=r;
if(l==r) return;
build(lc,l,mid); build(rc,mid+,r);
} void update(int x,int l,int r,int pos,int F) {
if(l==r) {
if(F) full[x]=,emp[x]=;
else emp[x]=,full[x]=;
return ;
}
if(pos<=mid) update(lc,l,mid,pos,F);
else update(rc,mid+,r,pos,F);
full[x]=(full[lc]&full[rc]);
emp[x]=(emp[lc]&emp[rc]);
ok[x]=(ok[x]&full[x]);
if(l!=&&!ok[x-]&&full[x]) get_ham(x-,xl[x-],xr[x-]);
} LL calc(int x,int y) {
LL d=R[x]-R[y];
return a[x]*d+b[x]+f[y];
} LL find(int x,int ll,int rr,int now) {
if(x==&&ll==&&rr==&&now==) {
int debug=;
int up=ham[x].size();
For(i,,up-) {
if(i) {
db k=(db)(f[ham[x][i]]-f[ham[x][i-]])/(db)(R[ham[x][i]]-R[ham[x][i-]]);
if(k<) {
int debug=;
}
}
LL rs=calc(now,ham[x][i]);
rs=rs;
}
}
if(ll==rr) return calc(now,sta[ll]);
int l=,r=ham[x].size();
while(l<r) {
if(l+==r) {
LL rs1=calc(now,ham[x][l-]),rs2=calc(now,ham[x][r-]);
return min(rs1,rs2);
}
LL rs1=calc(now,ham[x][mid-]),rs2=calc(now,ham[x][mid-]),rs3=calc(now,ham[x][mid]);
if(rs1>=rs2&&rs3>=rs2) return rs2;
if(rs1<=rs2&&rs2<=rs3) r=mid-;
else l=mid+;
}
return calc(now,ham[x][l-]);
} LL qry(int x,int l,int r,int ql,int qr,int now) {
if(ql>qr) return -;
if(x==&&l==&&r==&&ql==&&qr==&&now==) {
int debug=;
}
if(l>=ql&&r<=qr&&(ok[x]||l==r))
return find(x,l,r,now);
if(qr<=mid) return qry(lc,l,mid,ql,qr,now);
if(ql>mid) return qry(rc,mid+,r,ql,qr,now);
return min(qry(lc,l,mid,ql,qr,now),qry(rc,mid+,r,ql,qr,now));
} int H[N];
LL st[N][];
int stf[N][];
void solve(int x) {
if(x==) {
int debug=;
}
int y=x;
LL now=;
Rep(i,,) if(stf[y][i]&&now+st[y][i]<=lim[x]) {
now+=st[y][i];
y=stf[y][i];
}
int l=H[y],r=H[x];
f[x]=qry(,,n,l,r-,x);
} void dfs(int x) {
H[x]=H[fa[x]]+;
stf[x][]=fa[x];
For(i,,) {
stf[x][i]=stf[stf[x][i-]][i-];
st[x][i]=(st[x][i-]+st[stf[x][i-]][i-]);
}
if(x!=) solve(x); //f[x]+=R[x]*a[x]+b[x]; }
sta[++top]=x;
update(,,n,H[x],);
for(int i=fir[x];i;i=nxt[i]) {
R[to[i]]=R[x]+val[i];
st[to[i]][]=val[i];
dfs(to[i]);
}
top--;
update(,,n,H[x],);
} //#define DEBUG
int main() {
#ifdef DEBUG
freopen("ticket.in","r",stdin);
freopen("ticket.out","w",stdout);
#endif
read(n); read(t);
For(i,,n) {
LL w;
read(fa[i]); read(w);
add(fa[i],i,w);
read(a[i]); read(b[i]); read(lim[i]);
}
build(,,n);
dfs();
For(i,,n) printf("%lld\n",f[i]);
return ;
}
NOI2014的更多相关文章
- [BZOJ3672][UOJ#7][NOI2014]购票
[BZOJ3672][UOJ#7][NOI2014]购票 试题描述 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. ...
- [BZOJ3671][UOJ#6][NOI2014]随机数生成器
[BZOJ3671][UOJ#6][NOI2014]随机数生成器 试题描述 小H最近在研究随机算法.随机算法往往需要通过调用随机数生成函数(例如Pascal中的random和C/C++中的rand)来 ...
- [BZOJ3670][UOJ#5][NOI2014]动物园
[BZOJ3670][UOJ#5][NOI2014]动物园 试题描述 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅,只会卖萌向游客要吃的.为了整治动物园的不良风气,让动物们凭自己的真才实学 ...
- bzoj3668: [Noi2014]起床困难综合症
从高位到低位枚举期望的应该是ans最高位尽量取一.如果该数最高位为o的话能够取得1直接更新ans否则判断该位取1是否会爆m不会的话就加上. #include<cstdio> #includ ...
- uoj #5. 【NOI2014】动物园 kmp
#5. [NOI2014]动物园 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/5 Description 近日 ...
- bzoj 3672: [Noi2014]购票 树链剖分+维护凸包
3672: [Noi2014]购票 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 480 Solved: 212[Submit][Status][D ...
- NOI2014 动物园
3670: [Noi2014]动物园 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 174 Solved: 92[Submit][Status] D ...
- NOI2014 魔法森林
3669: [Noi2014]魔法森林 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 106 Solved: 62[Submit][Status] ...
- NOI2014 起床困难综合症
3668: [Noi2014]起床困难综合症 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 225 Solved: 153[Submit][Stat ...
- BZOJ_3670_[NOI2014]_动物园_(kmp)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3670 对于一个字符串,求出num数组,其中num[i]表示前i个字符构成的字串中不相重合的相同 ...
随机推荐
- 前端实现预览ppt,word,xls,pdf文件
1.前端实现pdf文件在线预览功能 ps:刚好工作上有这个需求,所以到处找了一下处理方案,大家有需要可以试一下这几种方案,找到合适自己的 方式一. pdf文件理论上可以在浏览器直接打开预览但是需要打开 ...
- 转载:vs2010 问题 >LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
原文链接:http://www.cnblogs.com/newpanderking/articles/3372969.html >LINK : fatal error LNK1123: 转换到 ...
- 使用自己的Python函数处理Protobuf中的字符串编码
我目前所在的项目是一个老项目,里面的字符串编码有点乱,数据库中有些是GB2312,有些是UTF8:代码中有些是GBK,有些是UTF8,代码中转来转去,经常是不太清楚当前这个字符串是什么编码,由于是老项 ...
- QT开发资料
QT开发入门资料 https://tmr.js.org/p/cc37608/ QT学习之路: https://www.devbean.net/
- 固定Linux虚拟IP地址
由于我的开发环境是在VMWare虚拟机里安装Centos,然后在host文件中设置拦截,这样就可以直接跳转虚拟机的CentOS,但是虚拟机的IP地址总是会变,就要随时修改host文件,很麻烦.决定虚拟 ...
- Algo: Binary search
二分查找的基本写法: #include <vector> #include <iostream> int binarySearch(std::vector<int> ...
- FastStone Capture 文件名设置小记录
我使用的FastStone Capture 的文件名设置 文件名称模板 fs$Y$M$D#####@ 起始于: [1] 重置 [ 选中] 新的一天自动重置为1
- laravel passport client_credentials
我是使用 Laravel 5.4 + Dingo Api + passport/jwt 两个验证方式 目前需要用到 passport 的 client_credentials 获取 token成功之后 ...
- Thinkphp 3.2 去掉index.php
1.httpd.conf中去掉LoadModule rewrite_module modules/mod_rewrite.so 前面的#号 2.httpd.conf 中 AllowOverride ...
- Java——super关键字
2.3 super关键字 ①super不是引用类型,super中存储的不是内存地址,super指向的不是父类对象. ②super代表的是当前子类对象中的父类型特征. ③什么时候使用super? 类和父 ...