题目大意:
t
t
t 次询问,先给一扇门
n
n
n 的钥匙,开了
n
n
n 门后,会给当前数字
a
i
a_i
ai 的门的钥匙。
比如样例一:给了第3个门的钥匙,第3个门打开后给2门的钥匙,打开第2个门之后给第1个门的钥匙。所以三个门都打开了
问能不能打开三个门。
解题思路:
用map存每一个门打开后所给门的钥匙号码,然后计数,看看是不是能开三个门。
代码如下:
#include <bits/stdc++.h>
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define dec(a,b,c) for(int a=b;a>=c;a--)
#define x first
#define y second
#define pb push_back
#define LL long long
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define INF 0x3f3f3f3f
#define PII pair<int,int>
#define pi 3.14159265358979323846
using namespace std;
void solve()
{
int n;
cin>>n;
map<int,int> mp;
rep(i,1,3)
{
int k;
cin>>k;
mp[i]=k;
}
int num=1;
while(mp[n]!=0)
{
num++;
n=mp[n];
}
if(num==3)
cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
题目大意:
给
n
n
n 个数字
m
m
m 次询问。
问从
l
l
l 楼飞到
r
r
r 楼,如果递增,无事发生,如果
a
i
>
a
i
+
1
a_i>a_{i+1}
ai>ai+1 ,就掉
a
i
−
a
i
+
1
a_i-a_{i+1}
ai−ai+1 滴血,问从
l
l
l 到
r
r
r ,需要掉多少滴血.
解题思路:
前缀和,存
a
i
−
a
i
+
1
a_i-a_{i+1}
ai−ai+1 的前缀和。但是要正向存一下,反向存一下,因为有
l
>
r
l>r
l>r 的情况,如样例。
#include <bits/stdc++.h>
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define dec(a,b,c) for(int a=b;a>=c;a--)
#define x first
#define y second
#define pb push_back
#define LL long long
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define INF 0x3f3f3f3f
#define PII pair<int,int>
#define pi 3.14159265358979323846
using namespace std;
const int N=1e5+10;
LL s1[N],a[N],s2[N];
void solve()
{
int n,m;
cin>>n>>m;
rep(i,1,n)
cin>>a[i];
rep(i,2,n)
s1[i]=s1[i-1]+max(0ll,a[i-1]-a[i]);
dec(i,n-1,1)
s2[i]=s2[i+1]+max(0ll,a[i+1]-a[i]);
while(m--)
{
int l,r;
cin>>l>>r;
if(l<r)
cout<<s1[r]-s1[l]<<endl;
else cout<<s2[r]-s2[l]<<endl;
}
}
题目大意:
给一个字符串,?可以替换为‘(’或者‘)’,请问是否存在唯一的变幻让这个字符串变成匹配的。
解题思路:
用
n
u
m
num
num 记录‘(’ 和 ‘)’匹配,用
k
k
k 来存 ?的个数,如果
n
u
m
=
0
num=0
num=0 了且
k
k
k 是1,就让
k
k
k 变成‘(’。
但是过程中有可能出现这种情况,比如说
)
?
)?
)? 这种情况,所以不能直接用?的个数来比较()的个数。
代码如下:
#include <bits/stdc++.h>
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define dec(a,b,c) for(int a=b;a>=c;a--)
#define x first
#define y second
#define pb push_back
#define LL long long
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define INF 0x3f3f3f3f
#define PII pair<int,int>
#define pi 3.14159265358979323846
using namespace std;
void solve()
{
string s;
cin>>s;
int num=0,k=0;
rep(i,0,s.size()-1)
{
if(s[i]=='(') num++;
if(s[i]==')') num--;
if(s[i]=='?') k++;
if(num+k==1)
num=1,k=0;
}
if(k<=abs(num)) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
题目大意:
n
n
n 行
m
m
m 列,每列的前
a
i
a_i
ai 个位置有障碍。问能不能从(x1,y1)到(x2,y2),但是要求每次在某个方向(上下左右)只能走k步。
解题思路:
用线段树或者st表保存一下某段区间的最大的障碍的位置。然后,如果想
a
b
s
(
x
1
−
x
2
)
abs(x1-x2)
abs(x1−x2) 或者
a
b
s
(
y
1
−
y
2
)
abs(y1-y2)
abs(y1−y2) 不能被
k
k
k 整除,那么必不能到。如果满足,再判断最长的障碍是否到达
x
1
+
k
∗
n
u
m
x_1+k*num
x1+k∗num(num为该式到达边界的最大的num)
代码如下:
#include <bits/stdc++.h>
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define dec(a,b,c) for(int a=b;a>=c;a--)
#define x first
#define y second
#define pb push_back
#define LL long long
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define INF 0x3f3f3f3f
#define PII pair<int,int>
#define pi 3.14159265358979323846
using namespace std;
const int N=2e5+10;
int n,m,a[N];
struct Node
{
int l,r;
int maxn;
}tr[N<<2];
void pushup(int u)
{
tr[u].maxn=max(tr[u<<1].maxn,tr[u<<1|1].maxn);
}
void build(int u,int l,int r)
{
if(l==r)
{
tr[u]={l,r,a[l]};
return;
}
tr[u].l=l,tr[u].r=r;
int mid=l+r>>1;
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
pushup(u);
}
int query(int u,int l,int r)
{
if(l<=tr[u].l&&r>=tr[u].r)
return tr[u].maxn;
int res=-INF,mid=tr[u].l+tr[u].r>>1;
if(l<=mid) res=max(res,query(u<<1,l,r));
if(r>mid) res=max(res,query(u<<1|1,l,r));
return res;
}
int main()
{
ios;
int n,m;
cin>>n>>m;
rep(i,1,m)
cin>>a[i];
build(1,1,m);
int q;
cin>>q;
while(q--)
{
int x1,x2,y1,y2,k;
cin>>x1>>y1>>x2>>y2>>k;
if(abs(x1-x2)%k||abs(y1-y2)%k)
cout<<"NO"<<endl;
else
{
if(y1>y2) swap(y1,y2);
int num=abs(n-x1)/k*k+x1;
if(query(1,y1,y2)>=num)
cout<<"NO\n";
else cout<<"YES\n";
}
}
return 0;
}