听说14,15年的题是最简单的,然后除了提答以外的不那么水的题都是以前讲过、做过的,都比较好想到,但是我实现起来却有各种Bug,也完全不能在5h里AC。。。太弱了

[NOI2014]起床困难综合症

纯粹的送分题,每一位分开枚举选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 ;
}

[NOI2014]魔法森林

听讲和讲过多次的题了。

传送门

【NOI2014】消除游戏

这题我不会啊。。我可以手算第一个点。。

据说标解是什么拆成12*12的格子然后咋个搞一下。。

[NOI2014]动物园

随便看了看觉得是水题,就不小心费了一个多小时

先没用脑袋写了一些什么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 ;
}

[NOI2014]随机数生成器

第一反应是树套树,差点都开始打了发现我是个大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;
}

[NOI2014]购票

之前轩神讲过,刚好最近想找这道题,结果它自己找上门了。

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的更多相关文章

  1. [BZOJ3672][UOJ#7][NOI2014]购票

    [BZOJ3672][UOJ#7][NOI2014]购票 试题描述  今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会.       ...

  2. [BZOJ3671][UOJ#6][NOI2014]随机数生成器

    [BZOJ3671][UOJ#6][NOI2014]随机数生成器 试题描述 小H最近在研究随机算法.随机算法往往需要通过调用随机数生成函数(例如Pascal中的random和C/C++中的rand)来 ...

  3. [BZOJ3670][UOJ#5][NOI2014]动物园

    [BZOJ3670][UOJ#5][NOI2014]动物园 试题描述 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅,只会卖萌向游客要吃的.为了整治动物园的不良风气,让动物们凭自己的真才实学 ...

  4. bzoj3668: [Noi2014]起床困难综合症

    从高位到低位枚举期望的应该是ans最高位尽量取一.如果该数最高位为o的话能够取得1直接更新ans否则判断该位取1是否会爆m不会的话就加上. #include<cstdio> #includ ...

  5. uoj #5. 【NOI2014】动物园 kmp

    #5. [NOI2014]动物园 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/5 Description 近日 ...

  6. bzoj 3672: [Noi2014]购票 树链剖分+维护凸包

    3672: [Noi2014]购票 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 480  Solved: 212[Submit][Status][D ...

  7. NOI2014 动物园

    3670: [Noi2014]动物园 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 174  Solved: 92[Submit][Status] D ...

  8. NOI2014 魔法森林

    3669: [Noi2014]魔法森林 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 106  Solved: 62[Submit][Status] ...

  9. NOI2014 起床困难综合症

    3668: [Noi2014]起床困难综合症 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 225  Solved: 153[Submit][Stat ...

  10. BZOJ_3670_[NOI2014]_动物园_(kmp)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3670 对于一个字符串,求出num数组,其中num[i]表示前i个字符构成的字串中不相重合的相同 ...

随机推荐

  1. 2018-8-10-wpf-DoEvents-

    title author date CreateTime categories wpf DoEvents lindexi 2018-08-10 19:16:51 +0800 2018-2-13 17: ...

  2. Oracle之视图联合查询加排序问题

    在公司修改bug,有这样的需求:需要从两张视图中查出相同字段的数据,按照导师姓名先排序,再按照学号排序 union联合两张表,SELECT * from((SELECT DS_ID,PYLX_ID,Y ...

  3. mount 挂载

    mount 挂载出现 这是咋回事.找了找度娘,说是磁盘没有格式化.好吧,mkfs ext4 /dev/sda4 ,提示 没有有效的快给格式化,好奇怪啊,昨天明明分号区了,我记错了. fdisk看一下, ...

  4. jq-demo-2种吸顶效果

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. nacos配置服务入门

    1.nacos服务端部署 参见官方文档:https://nacos.io/zh-cn/docs/quick-start.html 2.nacos配置中心功能使用 在pol文件中添加依赖: 在启动类中使 ...

  6. 「题解」:07.16NOIP模拟T2:通讯

    问题 B: 通讯 时间限制: 1 Sec  内存限制: 256 MB 题面 题目描述 “这一切都是命运石之门的选择.” 试图研制时间机器的机关SERN截获了中二科学家伦太郎发往过去的一条短 信,并由此 ...

  7. 移动Windows开始按钮到任务栏中的任何位置

    uses CommCtrl; procedure TForm1.Button1Click(Sender: TObject); var vHandle: THandle; vCount: Integer ...

  8. thinkphp 原生分页

    paginate() 是有三个参数: 第一个参数是 $listRows [int],也就是当前的页数 第二个参数是 $simple [boolean], 是否简洁模式或者总记录数 第三个参数是 $co ...

  9. NOIp2018集训test-9-15(联考二day1)

    T1.矩阵游戏 水题.每一行最后乘的数为x[i],每一列为y[i],暴力算第一行的列的贡献,每一行的列的贡献是公差为所有列的贡献之和的等差数列,然后每一行再乘上行的贡献求和即为答案. //Achen ...

  10. Spring-Security (学习记录四)--配置权限过滤器,采用数据库方式获取权限

    目录 1. 需要在spring-security.xml中配置验证过滤器,来取代spring-security.xml的默认过滤器 2. 配置securityMetadataSource,可以通过ur ...