G. Count the Trains
思路
思维。不断维护递减序列。
set内保存的是每节火车的头。对于一个修改,如果其前一个id的值比它大那就放入集合s。后面依次排出不符合严格递减序列的元素。复杂度O(mlogn)。
#include <bits/stdc++.h>
typedef long double ld;
typedef long long ll;
#define pb push_back
#define mk make_pair
#define mt make_tuple
#define eb emplace_back
#define pob pop_back
#define rz resize
#define mem(a,b) memset(a,b,sizeof(a))
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define debug(a) cout<<#a<<"="<<a<<endl;
#define qwe(i,a,b) for(int i=a;i<=b;i++)
#define ewq(i,a,b) for(int i=a;i>=b;i--)
inline ll rr(){ll f=1,x=0;char ch;do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');return f*x;}
using namespace std;
const ll INF=0x3f3f3f3f,inf=0x3f3f3f3f3f3f3f;
const ll mod[2]={int(1e9 + 7), 10007};
const int base[2]={29,31};
const int maxn=1e5+6;
ll qpow(ll x,ll n){ll ans=1;while(n>0){if(n&1)ans=ans*x%mod[1];x=x*x%mod[1];n>>=1;}return ans;}
int n,m;
int a[maxn];
void init(/* arguments */) {
n=rr(),m=rr();
for(int i=1;i<=n;i++) a[i]=rr();
}
int main(int argc, char const *argv[]) {
int t=rr();
while (t--) {
init();
set<int> s;
for(int i=1;i<=n;i++) {
if(s.empty() || a[i]<a[*s.rbegin()]) {
s.insert(i);
}
}
for(int i=0;i<m;i++) {
int x=rr(),k=rr();
a[x]-=k;
auto it=s.upper_bound(x);
if(it!=s.begin() && a[*prev(it)]>a[x]) s.insert(x);
else if(it==s.begin()) s.insert(x);
while (1) {
it=s.upper_bound(x);
if(it==s.end()) break;
if(a[*it]>=a[x]) s.erase(*it);
else break;
}
std::cout << (int)s.size() << ' ';
}
std::cout << '\n';
}
return 0;
}
F. Shifting String
思路
画出来就是很多个圈,他们之间能不断右移。最小交换次数就是所有圈的最小右移最小周期数的最小公倍数。思路很好想,主要在于怎么解决。
处理方法上想到dfs,求出圈的序列。然后不断枚举可能性求出最小的右移周期。考虑到最长有200个,就选择循环求出圈的序列。但是又由于不断枚举可能性会导致复杂度过高。问题主要在于如何在O(L)时间内求出最小的右移次数(L为这个圈的长度)。然后想到kmp算法…kmp求最长公共前后缀。但是这是不对的。(痛苦面具)。
然后看了别人的枚举,发现枚举周期只要枚举L的因子就行了,…(沉默了),瞬间恍然大悟。复杂度O(LlogL)。
#include <bits/stdc++.h>
typedef long double ld;
typedef long long ll;
#define pb push_back
#define mk make_pair
#define mt make_tuple
#define eb emplace_back
#define pob pop_back
#define rz resize
#define mem(a,b) memset(a,b,sizeof(a))
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define debug(a) cout<<#a<<"="<<a<<endl;
#define qwe(i,a,b) for(int i=a;i<=b;i++)
#define ewq(i,a,b) for(int i=a;i>=b;i--)
inline ll rr(){ll f=1,x=0;char ch;do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');return f*x;}
using namespace std;
const ll INF=0x3f3f3f3f,inf=0x3f3f3f3f3f3f3f;
const ll mod[2]={int(1e9 + 7), 10007};
const int base[2]={29,31};
const int maxn=2e2+6;
ll qpow(ll x,ll n){ll ans=1;while(n>0){if(n&1)ans=ans*x%mod[1];x=x*x%mod[1];n>>=1;}return ans;}
int n;
int a[maxn],vis[maxn];
string s;
void init(/* arguments */) {
n=rr();
cin>>s;
for(int i=0;i<n;i++) a[i]=rr()-1;
mem(vis,0);
}
ll gcd(ll a,ll b) {
while (b^=a^=b^=a%=b);
return a;
}
ll lcm(ll a,ll b) {
return a*b/gcd(a,b);
}
bool check(string &b,int t) {
int L=b.size();
if(L%t) return 0;
for(int i=0;i+t<L;i++) {
if(b[i]!=b[i+t]) return 0;
}
return 1;
}
int main(int argc, char const *argv[]) {
int t=rr();
while (t--) {
init();
ll ans=1;
for(int i=0;i<n;i++) {
if(vis[i]) continue;
string t;
while (!vis[i]) {
t+=s[i];
vis[i]=1;
i=a[i];
}
int T=1;
while (!check(t,T)) T++;
ans=lcm(ans,T);
}
std::cout << ans << '\n';
}
return 0;
}
E. Price Maximization
思路
余数能匹配出>=k那么ans+1。
要调用multiset的lower_bound而不能直接调用lower_bound否则超时。
#include <bits/stdc++.h>
typedef long double ld;
typedef long long ll;
#define pb push_back
#define mk make_pair
#define mt make_tuple
#define eb emplace_back
#define pob pop_back
#define rz resize
#define mem(a,b) memset(a,b,sizeof(a))
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define debug(a) cout<<#a<<"="<<a<<endl;
#define qwe(i,a,b) for(int i=a;i<=b;i++)
#define ewq(i,a,b) for(int i=a;i>=b;i--)
inline ll rr(){ll f=1,x=0;char ch;do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');return f*x;}
using namespace std;
const ll INF=0x3f3f3f3f,inf=0x3f3f3f3f3f3f3f;
const ll mod[2]={int(1e9 + 7), 10007};
const int base[2]={29,31};
const int maxn=2e5+6;
ll qpow(ll x,ll n){ll ans=1;while(n>0){if(n&1)ans=ans*x%mod[1];x=x*x%mod[1];n>>=1;}return ans;}
int n,k;
int a[maxn];
void init(/* arguments */) {
n=rr(),k=rr();
}
int main(int argc, char const *argv[]) {
int t=rr();
while (t--) {
init();
multiset<int> s;
ll ans=0;
qwe(i,0,n-1) {
a[i]=rr();
ans+=(a[i]/k);
a[i]%=k;
s.insert(a[i]);
}
while (!s.empty()) {
int x=*s.begin();
s.erase(s.begin());
// auto it=lower_bound(all(s),k-x);
auto it=s.lower_bound(k-x);
if(it!=s.end()) {
ans++;
s.erase(it);
}
}
std::cout << ans << '\n';
}
return 0;
}
D. Black and White Stripe
思路
滑动窗口,移动时维护窗口内黑色方块或者白色方块的个数。
#include <bits/stdc++.h>
typedef long double ld;
typedef long long ll;
#define pb push_back
#define mk make_pair
#define mt make_tuple
#define eb emplace_back
#define pob pop_back
#define rz resize
#define mem(a,b) memset(a,b,sizeof(a))
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define debug(a) cout<<#a<<"="<<a<<endl;
#define qwe(i,a,b) for(int i=a;i<=b;i++)
#define ewq(i,a,b) for(int i=a;i>=b;i--)
inline ll rr(){ll f=1,x=0;char ch;do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');return f*x;}
using namespace std;
const ll INF=0x3f3f3f3f,inf=0x3f3f3f3f3f3f3f;
const ll mod[2]={int(1e9 + 7), 10007};
const int base[2]={29,31};
const int maxn=2e5+6;
ll qpow(ll x,ll n){ll ans=1;while(n>0){if(n&1)ans=ans*x%mod[1];x=x*x%mod[1];n>>=1;}return ans;}
int n,k;
int a[maxn],b[maxn];
string s;
void init(/* arguments */) {
n=rr();
qwe(i,0,n-1) a[i]=rr();
qwe(i,0,n-1) b[i]=rr();
}
int main(int argc, char const *argv[]) {
int t=rr();
while (t--) {
n=rr(),k=rr();
cin>>s;
int w=0,b=0;
for(int i=0;i<k;i++){
if(s[i]=='W') w++;
else b++;
}
int le=0,ri=k-1,ans=INF;
ans=min(ans,k-b);
while (ri<n) {
le++;
ri++;
if(ri>=n) break;
if(s[le-1]=='W') w--;
else b--;
if(s[ri]=='W') w++;
else b++;
ans=min(ans,k-b);
}
std::cout << ans << '\n';
}
return 0;
}
C. Restoring the Duration of Tasks
C - Restoring the Duration of Tasks
思路
维护当前的截至时间。
#include <bits/stdc++.h>
typedef long double ld;
typedef long long ll;
#define pb push_back
#define mk make_pair
#define mt make_tuple
#define eb emplace_back
#define pob pop_back
#define rz resize
#define mem(a,b) memset(a,b,sizeof(a))
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define debug(a) cout<<#a<<"="<<a<<endl;
#define xx first
#define yy second
#define qwe(i,a,b) for(int i=a;i<=b;i++)
#define ewq(i,a,b) for(int i=a;i>=b;i--)
inline ll rr(){ll f=1,x=0;char ch;do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');return f*x;}
using namespace std;
const ll INF=0x3f3f3f3f,inf=0x3f3f3f3f3f3f3f;
const ll mod[2]={int(1e9 + 7), 10007};
const int base[2]={29,31};
const int maxn=2e5+6;
ll qpow(ll x,ll n){ll ans=1;while(n>0){if(n&1)ans=ans*x%mod[1];x=x*x%mod[1];n>>=1;}return ans;}
int n;
int a[maxn],b[maxn];
void init(/* arguments */) {
n=rr();
qwe(i,0,n-1) a[i]=rr();
qwe(i,0,n-1) b[i]=rr();
}
int main(int argc, char const *argv[]) {
int t=rr();
while (t--) {
init();
int en=0;
int ans[maxn]={0};
for(int i=0;i<n;i++) {
if(a[i]<en) { // 开始比结束早
if(b[i]>en) {
ans[i]=b[i]-en;
}
en=max(en,b[i]);
}
if(a[i]>=en) {
ans[i]=b[i]-a[i];
en=b[i];
}
}
qwe(i,0,n-1) std::cout << ans[i] << ' ';
std::cout << '\n';
}
return 0;
}
B. Array Decrements
思路
计算出每个id上a-b的值,记录最大值。如果存在ai-bi的值比最大值小,那么bi必须是0.其次不能存在ai<bi的情况。
#include <bits/stdc++.h>
typedef long double ld;
typedef long long ll;
#define pb push_back
#define mk make_pair
#define mt make_tuple
#define eb emplace_back
#define pob pop_back
#define rz resize
#define mem(a,b) memset(a,b,sizeof(a))
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define debug(a) cout<<#a<<"="<<a<<endl;
#define xx first
#define yy second
#define qwe(i,a,b) for(int i=a;i<=b;i++)
#define ewq(i,a,b) for(int i=a;i>=b;i--)
inline ll rr(){ll f=1,x=0;char ch;do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');return f*x;}
using namespace std;
const ll INF=0x3f3f3f3f,inf=0x3f3f3f3f3f3f3f;
const ll mod[2]={int(1e9 + 7), 10007};
const int base[2]={29,31};
const int maxn=2e5+6;
ll qpow(ll x,ll n){ll ans=1;while(n>0){if(n&1)ans=ans*x%mod[1];x=x*x%mod[1];n>>=1;}return ans;}
int n;
int a[maxn],b[maxn];
int main(int argc, char const *argv[]) {
int t=rr();
while (t--) {
n=rr();
qwe(i,0,n-1) a[i]=rr();
qwe(i,0,n-1) b[i]=rr();
if(n==1) {
if(a[0]>=b[0]){std::cout << "YES" << '\n';}
else std::cout << "NO" << '\n';
continue;
}
int maxi=-INF,fl=0;
qwe(i,0,n-1) {
a[i]-=b[i];
maxi=max(maxi,a[i]);
if(a[i]<0) {fl=1;break;}
}
if(fl) {
std::cout << "NO" << '\n';
continue;
}
fl=0;
qwe(i,0,n-1) {
if(a[i]!=maxi && b[i]) {
fl=1;
break;
}
}
if(fl) std::cout << "NO" << '\n';
else std::cout << "YES" << '\n';
}
return 0;
}
A. Print a Pedestal (Codeforces logo?)
A - Print a Pedestal (Codeforces logo?)
思路
设右边x,左边x+1,右边x+2。求出x,根据余数分配给中间和左边值,中间优先级高。
#include <bits/stdc++.h>
typedef long double ld;
typedef long long ll;
#define pb push_back
#define mk make_pair
#define mt make_tuple
#define eb emplace_back
#define pob pop_back
#define rz resize
#define mem(a,b) memset(a,b,sizeof(a))
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define debug(a) cout<<#a<<"="<<a<<endl;
#define xx first
#define yy second
#define qwe(i,a,b) for(int i=a;i<=b;i++)
#define ewq(i,a,b) for(int i=a;i>=b;i--)
inline ll rr(){ll f=1,x=0;char ch;do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');return f*x;}
using namespace std;
const ll INF=0x3f3f3f3f,inf=0x3f3f3f3f3f3f3f;
const ll mod[2]={int(1e9 + 7), 10007};
const int base[2]={29,31};
const int maxn=2e5+6;
ll qpow(ll x,ll n){ll ans=1;while(n>0){if(n&1)ans=ans*x%mod[1];x=x*x%mod[1];n>>=1;}return ans;}
void init(/* arguments */) {
}
int main(int argc, char const *argv[]) {
int t=rr();
while (t--) {
int d=rr();
int ans=(d-3)/3;
int r=d%3;
int a,b,c;
b=ans+2+(r>0);
r--;
a=ans+1+(r>0);
r--;
c=ans;
std::cout << a<<' '<< b<<' '<<c << '\n';
}
return 0;
}