题目
A Stickers and Toys
#include<bits/stdc++.h>
using namespace std;
int main(){
int p;
scanf("%d",&p);
while(p--){
int n,s,t;
scanf("%d%d%d",&n,&s,&t);
int a,b,c;
c=s+t-n;
a=s-c;
b=t-c;
cout<<max(a,b)+1<<endl;
}
}
B Letters Shop
#include<bits/stdc++.h>
using namespace std;
int n;
vector<int>vec[26];
int pos[26];
int main(){
scanf("%d",&n);
string s;
cin>>s;
for(int i=0;i<s.size();i++){
vec[s[i]-'a'].push_back(i);
}
int q;
scanf("%d",&q);
while(q--){
int ans=0;
memset(pos,0,sizeof(pos));
string tmp;
cin>>tmp;
for(int i=0;i<tmp.size();i++){
ans=max(ans,vec[tmp[i]-'a'][pos[tmp[i]-'a']++]);
}
cout<<ans+1<<endl;
}
}
C Vasya And Array
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=1e5+10;
vector<pair<ll,ll> >vec,Vec[2];
bool L[maxn],R[maxn];
ll ans[maxn];
multiset<ll>s;
int main(){
ll n,m;
scanf("%lld%lld",&n,&m);
for(ll i=1;i<=m;i++){
ll op,l,r;
scanf("%lld%lld%lld",&op,&l,&r);
if(!op)
Vec[op].push_back(make_pair(l,r));
if(op){
vec.push_back(make_pair(l,-i));
vec.push_back(make_pair(r,i));
}
}
sort(vec.begin(),vec.end());
ll sz=vec.size();
ll curs,cure;
for(ll i=0;i<sz;i++){
if(vec[i].second<0){
if(s.empty()){
curs=vec[i].first;
L[vec[i].first]=true;
}
s.insert(-vec[i].second);
}
else{
s.erase(vec[i].second);
if(s.empty()){
R[vec[i].first]=true;
cure=vec[i].first;
Vec[1].push_back(make_pair(curs,cure));
}
}
}
bool flag=true;
ll sz0=Vec[0].size();
ll sz1=Vec[1].size();
for(ll i=0;i<sz0;i++){
for(ll j=0;j<sz1;j++){
if(Vec[0][i].first>=Vec[1][j].first&&Vec[0][i].second<=Vec[1][j].second){
flag=false;
break;
}
}
if(!flag)
break;
}
if(!flag){
puts("NO");
return 0;
}
ll cur=1;
flag=false;
for(ll i=n;i>0;i--){
if(R[i])flag=true;
if(L[i])flag=false;
if(flag)ans[i]=cur;
else ans[i]=cur++;
}
puts("YES");
for(ll i=1;i<=n;i++){
printf("%lld%c",ans[i],i==n?'\n':' ');
}
}
D Subarray Sorting
线段树最小值,枚举b中的数,判断当前b中的数是否为a中从1到该数在a中的位置这一区间内的最小值,并把a中这一数更新为INF
#include<bits/stdc++.h>
#define lson(x) x<<1
#define rson(x) x<<1|1
using namespace std;
const int maxn = 3e5+ 10;
const int INF=0x3f3f3f3f;
int a[maxn],b[maxn],pos[maxn];
struct Segment_tree
{
int l, r, Min;
}tree[maxn<<2];
int n,m;
void push_up(int x) {
tree[x].Min = min(tree[lson(x)].Min, tree[rson(x)].Min);
}
void build(int root, int l, int r) {
tree[root].Min = INF;
tree[root].l = l;
tree[root].r = r;
if (l == r) {
tree[root].Min = a[l];
return;
}
int mid = (l + r) >> 1;
build(lson(root), l, mid);
build(rson(root), mid + 1, r);
push_up(root);
}
void update(int root, int pos, int val) {
if (tree[root].l == tree[root].r) {
tree[root].Min = val;
return;
}
int mid = (tree[root].l + tree[root].r) >>1;
if (pos<=mid)
update(lson(root), pos, val);
else
update(rson(root), pos, val);
push_up(root);
}
int querymin(int root, int l, int r) {
if (tree[root].l >=l&& tree[root].r<=r) {
return tree[root].Min;
}
int mid = (tree[root].l + tree[root].r) >>1;
if (r <= mid)
return querymin(lson(root), l, r);
else if (l > mid)
return querymin(rson(root), l, r);
else
return min(querymin(lson(root), l, mid), querymin(rson(root), mid + 1, r));
}
vector<int>A[maxn],B[maxn];
int main() {
int t;
scanf("%d",&t);
while (t--) {
scanf("%d", &n);
for(int i=1;i<=n;i++)A[i].clear(),B[i].clear();
for (int i = 1; i <= n; i++){
scanf("%d", &a[i]);
A[a[i]].push_back(i);
}
for(int i=1;i<=n;i++){
scanf("%d",&b[i]);
B[b[i]].push_back(i);
}
bool flag=true;
for(int i=1;i<=n;i++){
if(A[i].size()!=B[i].size()){
flag=false;
break;
}
for(int j=0;j<A[i].size();j++){
pos[B[i][j]]=A[i][j];
}
}
if(!flag){puts("NO");continue;}
build(1, 1, n);
for(int i=1;i<=n;i++){
if(querymin(1,1,pos[i])!=b[i]){
//cout<<b[i]<<' '<<querymin(1,1,pos[b[i]])<<endl;
flag=false;
break;
}
update(1,pos[i],INF);
}
if(flag)puts("YES");
else puts("NO");
}
return 0;
}
E Tree Painting
选取跟使求子树大小和最大,换根dp,先任选一个根求出答案,然后可推出相邻点为根的答案。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=2e5+10;
struct Edge{
ll v,next;
}e[maxn<<1];
ll head[maxn];
ll ans[maxn];
ll sz[maxn];
ll cnt;
ll Ans;
void add(ll u,ll v){
e[cnt].v=v;
e[cnt].next=head[u];
head[u]=cnt++;
}
void getsize(ll u,ll f){
sz[u]=1;
for(ll i=head[u];~i;i=e[i].next){
ll v=e[i].v;
if(v==f)continue;
getsize(v,u);
sz[u]+=sz[v];
}
ans[1]+=sz[u];
}
void getans(ll u,ll f){
for(ll i=head[u];~i;i=e[i].next){
ll v=e[i].v;
if(v==f)continue;
ans[v]=ans[u]-sz[u]-sz[v];
ll szu=sz[u],szv=sz[v];
sz[v]=szu;
sz[u]=szu-szv;
ans[v]+=sz[v]+sz[u];
getans(v,u);
sz[v]=szv;
sz[u]=szu;
}
Ans=max(Ans,ans[u]);
}
int main(){
memset(head,-1,sizeof(head));
ll n;
scanf("%lld",&n);
for(ll i=1;i<n;i++){
ll u,v;
scanf("%lld%lld",&u,&v);
add(u,v);
add(v,u);
}
getsize(1,-1);
getans(1,-1);
cout<<Ans<<endl;
}