int T,n,a,b,c,d,m,st,ed,l,r;
int main() {
qr(T); for(int t=1;t<=T;t++) {
qr(n); qr(a); qr(b); qr(c); qr(d);
st=a-b; ed=a+b; l=c-d; r=c+d;
if(st*n>r||ed*n<l) {puts("NO"); continue;}
puts("YES");
}
return 0;
}
前缀和
int T,k,n,a[N],s[N],ans,pos;
int main() {
qr(T); while(T--) {
qr(n);qr(k);
for(int i=1;i<=n;i++)
qr(a[i]);
for(int i=2;i<n;i++) {
if(a[i-1]<a[i]&&a[i]>a[i+1]) s[i]=1;
else s[i]=0;
s[i]+=s[i-1];
}
pos=1;ans=0;
for(int i=1;i+k-1<=n;i++)
if(ans<s[i+k-2]-s[i]) ans=s[i+k-2]-s[i],pos=i;
pr1(ans+1); pr2(pos);
}
return 0;
}
一个合法的排列类似:
5 3 4 1 2
从1开始往右扫直到碰到第n+1个位置或者已经访问过的位置,此时跳到应该扫描的位置并重复操作.
如上例:扫描1 2,扫描3 4,扫描5
如果不能扫描完全则输出-1.
int T,n,a[N],ans,vis[N],num,p[N],now;
int main() {
qr(T); while(T--) {
qr(n); vis[n+1]=++num;
for(int i=1;i<=n;i++) qr(a[i]),p[a[i]]=i;
now=p[1]-1; ans=1;
for(int i=1;i<=n;i++)
if(p[i]==now+1) vis[p[i]]=num,now++;
else if(vis[now+1]==num) vis[now=p[i]]=num;
else {ans=0; break;}
puts(ans?"YES":"NO");
}
return 0;
}
考察简单的DP+状态压缩.
设 表示 最大数的当前 位选择的数.
保障最大的措施是从后往前枚举和数字从小到大枚举.
int n,m,f[N][N],pre[N][N],a[N],cnt[N],num[11]={119,18,93,91,58,107,111,82,127,123,};
char s[N];
int g(char *s) {
int y=0;
for(int i=0;i<7;i++) y=y*2+(s[i]-'0');
return y;
}
bool pd(int x,int y) {return ((x&num[y])==x);}//x->y
int main() {
for(int i=1;i<=(1<<7);i++)cnt[i]=cnt[i&(i-1)]+1;
qr(n); qr(m); memset(f,-1,sizeof f);
for(int i=1;i<=n;i++) {
scanf("%s",s);
a[i]=g(s);
}
for(int i=0,j;i<=9;i++) if(pd(a[n],i)) f[n][cnt[num[i]^a[n]]]=i;
for(int i=n-1;i>0;i--) {
for(int j=0,k;j<=9;j++)
if(pd(a[i],j)) {
k=cnt[num[j]^a[i]];
for(int x=k;x<=m;x++)
if(f[i+1][x-k]!=-1) {
f[i][x]=j;
pre[i][x]=x-k;
}
}
}
if(f[1][m]==-1) puts("-1");
else {
int x=m;
for(int i=1;i<=n;i++)
qw(f[i][x]),x=pre[i][x];
}
return 0;
}
轮搜索即可.
复杂度大概为
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int N=10010,G=1010;
int x[N],n,m,r,g,ans=2e9;
bool v[N][G];
vector<int> q[N];
void dfs(int now,int u,int t) {
if(u<1||u>m||t<0||v[u][t]) return ;
v[u][t]=1;
if(u==m) ans=min(ans,now*(g+r)+g-t);
if(!t) q[now+1].pb(u);
else {
dfs(now,u-1,t-(x[u]-x[u-1]));
dfs(now,u+1,t-(x[u+1]-x[u]));
}
}
void qr(int &x) {scanf("%d",&x);}
int main() {
qr(n); qr(m);
for(int i=1;i<=m;i++) qr(x[i]);
qr(g); qr(r);
sort(x+1,x+m+1); q[0].pb(1);
for(int i=0;i<=m;i++) {
for(int j:q[i]) dfs(i,j,g);
if(ans!=2e9) {printf("%d\n",ans); exit(0);}
}
puts("-1");
return 0;
}
#include<cstdio>
#include<vector>
#define pi pair<int,int>
using namespace std;
const int N=1e6+10;
vector<int>e[N];
int n,m,cnt,deg[N];
pi ans[N*3];
void dfs(int x,int t,int f) {
int fir=t;
ans[++cnt]=pi(x,t);
for(int y:e[x]) if(y^f) {
if(t==m) {
t=m-deg[x];
ans[++cnt]=pi(x,t);
}
dfs(y,++t,x);
ans[++cnt]=pi(x,t);
}
if(t!=fir-1&&x>1) ans[++cnt]=pi(x,fir-1);//保障回溯时为fir-1
}
void add(int x,int y) {deg[x]++; e[x].push_back(y);}
int main() {
scanf("%d",&n);
for(int i=1,x,y;i<n;i++)
scanf("%d %d",&x,&y),add(x,y),add(y,x);
for(int i=1;i<=n;i++) m=max(m,deg[i]);//最大的t值显然为maxdeg
dfs(1,0,0);printf("%d\n",cnt);
for(int i=1;i<=cnt;i++) printf("%d %d\n",ans[i].first,ans[i].second);
return 0;
}
暂无题解
这是个有修改的问题,不难想到线段树.
同时,又有连续段的快速匹配,不难想到Hash.
显然如果一个串中有一个子段是类似"2 -1".这样整个串都不合法.
所以我们线段树节点要维护3个量(左边右括号,右边左括号,是否整段不合法).
这样我们就可以忽略中间匹配消去的部分,同时快速合并.
合并的时候细节较多,要非常注意.
复杂度
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define gc getchar()
#define lc (x<<1)
#define rc (x<<1|1)
using namespace std;
typedef long long ll;
const int N=1e5+10;
const int b1=233,m1=1e9+9;
const int b2=131,m2=998244353;
void qr(int &x) {
char c=gc; x=0; int f=1;
while(!isdigit(c)){if(c=='-')f=-1; c=gc;}
while(isdigit(c))x=x*10+c-'0',c=gc;
x*=f;
}
int p1[N],p2[N];
//Hash
struct str {
int len,h1,h2;
str(int x=0) {h1=h2=x; len=x>0;}
inline str operator +(str b) const {
str c; c.len=len+b.len;
c.h1=((ll)h1*p1[b.len]+b.h1)%m1;
c.h2=((ll)h2*p2[b.len]+b.h2)%m2;
return c;
}
inline str operator -(str b) const {
str c; c.len=len-b.len;
c.h1=(h1-(ll)b.h1*p1[c.len]%m1+m1)%m1;
c.h2=(h2-(ll)b.h2*p2[c.len]%m2+m2)%m2;
return c;
}
bool operator ==(str b) const {return len==b.len&&h1==b.h1&&h2==b.h2;}
}L,R;
//线段树
struct node {
str l,r; bool flag;//和左/右匹配的右/左括号的hash.是否无效.
node(){l=r=str();flag=0;}
}t[N<<2];
void queryr(int x,int l,int r,int len) {//找x右侧的len个未匹配左括号
while(R.len^len) {
if(l==r) {R=R+t[x].r; return ;}
int mid=(l+r)>>1;
if(R.len+t[rc].r.len-L.len>=len||t[rc].flag) x=rc,l=mid+1;
else {
if(t[rc].r.len>L.len) R=R+(t[rc].r-L),L=str();
else L=L-t[rc].r;
L=t[rc].l+L;
x=lc; r=mid;
}
}
}
void queryl(int x,int l,int r,int len) {//找x左侧的len个未匹配的右括号
while(L.len^len) {
if(l==r) {L=L+t[x].l; return ;}
int mid=(l+r)>>1;
if(L.len+t[lc].l.len-R.len>=len||t[lc].flag) x=lc,r=mid;
else {
if(t[lc].l.len<R.len) R=R-t[lc].l;
else L=L+(t[lc].l-R),R=str();
R=t[lc].r+R;
x=rc;l=mid+1;
}
}
}
node pushup(int x,int l,int r,node a,node b) {
node c; c.flag=a.flag|b.flag;
if(c.flag) return c;
if(!a.r.len) {c.l=a.l+b.l; c.r=b.r; return c;}
if(!b.l.len) {c.r=b.r+a.r; c.l=a.l; return c;}
L=R=str();
int mid=(l+r)>>1;
if(a.r.len<b.l.len) {
queryl(rc,mid+1,r,a.r.len);
if(a.r==L) c.l=a.l+(b.l-a.r),c.r=b.r;
else c.flag=1;
}
else {
queryr(lc,l,mid,b.l.len);
if(b.l==R) c.r=b.r+(a.r-b.l),c.l=a.l;
else c.flag=1;
}
return c;
}
void pushup_all(int x,int l,int r) {t[x]=pushup(x,l,r,t[lc],t[rc]);}
void change(int x,int l,int r,int pos,int d) {
if(l==r) {
t[x]=node();
if(d>0) t[x].r=str(d);
else t[x].l=str(-d);
return ;
}
int mid=(l+r)>>1;
if(pos<=mid) change(lc,l,mid,pos,d);
else change(rc,mid+1,r,pos,d);
pushup_all(x,l,r);
}
node query(int x,int l,int r,int L,int R) {
if(L==l&&r==R) return t[x];
int mid=(l+r)>>1;
if(R<=mid) return query(lc,l,mid,L,R);
else if(mid<L) return query(rc,mid+1,r,L,R);
else {
node t1=query(lc,l,mid,L,mid);
node t2=query(rc,mid+1,r,mid+1,R);
return pushup(x,l,r,t1,t2);
}
}
int n,m,a[N];
void bt(int x,int l,int r) {
if(l==r) {
int d=a[l];
if(d>0) t[x].r=str(d);
else t[x].l=str(-d);
return ;
}
int mid=(l+r)>>1;
bt(lc,l,mid);
bt(rc,mid+1,r);
pushup_all(x,l,r);
}
int main() {
qr(n); qr(m);
p1[0]=1;for(int i=1;i<=n;i++) p1[i]=(ll)p1[i-1]*b1%m1;
p2[0]=1;for(int i=1;i<=n;i++) p2[i]=(ll)p2[i-1]*b2%m2;
for(int i=1;i<=n;i++) qr(a[i]);
bt(1,1,n); qr(m);
while(m--) {
int op,x,y; qr(op); qr(x); qr(y);
if(op==1) change(1,1,n,x,y);
else {
node res=query(1,1,n,x,y);
if(res.flag||res.l.len||res.r.len) puts("No");
else puts("Yes");
}
}
return 0;
}