A - ABA and BAB
A - ABA and BAB (atcoder.jp)
這道題我一開始想復雜了,一直在想怎么dp,沒注意到其實是個很簡單的規律題。
我們可以發現我們住需要統計一下類似ABABA這樣不同字母相互交替的所有子段的長度,而每個字段的的情況有(長度+1)/2種,最后所有字段情況的乘積就是最終答案。
#pragma GCC optimize(3) //O2優化開啟
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
// const int mod=1e9+7;
const int MX=0x3f3f3f3f3f3f3f3f;
//inline int read() //快讀
//{
// int xr=0,F=1; char cr;
// while(cr=getchar(),cr<'0'||cr>'9') if(cr=='-') F=-1;
// while(cr>='0'&&cr<='9')
// xr=(xr<<3)+(xr<<1)+(cr^48),cr=getchar();
// return xr*F;
//}
//void write(int x) //快寫
//{
// if(x<0) putchar('-'),x=-x;
// if(x>9) write(x/10); putchar(x%10+'0');
//}
// 比 unordered_map 更快的哈希表
// #include <ext/pb_ds/assoc_container.hpp>
// using namespace __gnu_pbds;
// const int RANDOM = chrono::high_resolution_clock::now().time_since_epoch().count();
// struct chash {
// int operator()(int x) const { return x ^ RANDOM; }
// };
// typedef gp_hash_table<int, int, chash> hash_t;
constexpr ll mod = 1e9 + 7; //此處為自動取模的數
class modint{ll num;
public:modint(ll num = 0) :num(num % mod){}ll val() const {return num;}modint pow(ll other) {modint res(1), temp = *this;while(other) {if(other & 1) res = res * temp;temp = temp * temp;other >>= 1;}return res;}constexpr ll norm(ll num) const {if (num < 0) num += mod;if (num >= mod) num -= mod;return num;}modint inv(){ return pow(mod - 2); }modint operator+(modint other){ return modint(num + other.num); }modint operator-(){ return { -num }; }modint operator-(modint other){ return modint(-other + *this); }modint operator*(modint other){ return modint(num * other.num); }modint operator/(modint other){ return *this * other.inv(); }modint &operator*=(modint other) { num = num * other.num % mod; return *this; }modint &operator+=(modint other) { num = norm(num + other.num); return *this; }modint &operator-=(modint other) { num = norm(num - other.num); return *this; }modint &operator/=(modint other) { return *this *= other.inv(); }friend istream& operator>>(istream& is, modint& other){ is >> other.num; other.num %= mod; return is; }friend ostream& operator<<(ostream& os, modint other){ other.num = (other.num + mod) % mod; return os << other.num; }
};int n;
string s;
void icealsoheat(){cin>>n;cin>>s;s=" "+s;int res=1;modint ans=1;for(int i=2;i<=n;i++){if(s[i]!=s[i-1]){res++;}else{if(res>=3){ans*=(res+1)/2;}res=1;}}if(res>=3){ans*=(res+1)/2;}cout<<ans;
}
signed main(){ios::sync_with_stdio(false); //int128不能用快讀!!!!!!cin.tie();cout.tie();int _yq;_yq=1;// cin>>_yq;while(_yq--){icealsoheat();}
}
//
//??? ???????????
//????????????? ???????????
//??????????????????????????
//????????????????????? ?????
//???????????????????????
//??????????????????? ????
//????????????????????????
//????????????????????????
//???????????????????????
//??????????????????????
//??????????????
//????????????
//
B - Improve Inversions
B - Improve Inversions (atcoder.jp)
這題確實不好想,但是get到點兒了就會覺得其實也不難。
我們需要盡可能的把逆序對最大化,從樣例三我們可以發現,我們不妨確立左邊一個要交換的下標i,然后找下標大于等于i+k,數值從大到小的找小于ai的數字,并依次與i的數字進行交換。為了盡可能減少替換的影響,我們按數值從小到大的次序去找這個下標i,從而參與上述的交換。因為我們是按從小到大的順序的,所以小的數字參與交換并不會影響后面大的數字該交換的逆序對。
#pragma GCC optimize(3) //O2優化開啟
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
// const int mod=1e9+7;
const int MX=0x3f3f3f3f3f3f3f3f;
//inline int read() //快讀
//{
// int xr=0,F=1; char cr;
// while(cr=getchar(),cr<'0'||cr>'9') if(cr=='-') F=-1;
// while(cr>='0'&&cr<='9')
// xr=(xr<<3)+(xr<<1)+(cr^48),cr=getchar();
// return xr*F;
//}
//void write(int x) //快寫
//{
// if(x<0) putchar('-'),x=-x;
// if(x>9) write(x/10); putchar(x%10+'0');
//}
// 比 unordered_map 更快的哈希表
// #include <ext/pb_ds/assoc_container.hpp>
// using namespace __gnu_pbds;
// const int RANDOM = chrono::high_resolution_clock::now().time_since_epoch().count();
// struct chash {
// int operator()(int x) const { return x ^ RANDOM; }
// };
// typedef gp_hash_table<int, int, chash> hash_t;
// constexpr ll mod = 1e9 + 7; //此處為自動取模的數
// class modint{
// ll num;
// public:
// modint(ll num = 0) :num(num % mod){}// ll val() const {
// return num;
// }// modint pow(ll other) {
// modint res(1), temp = *this;
// while(other) {
// if(other & 1) res = res * temp;
// temp = temp * temp;
// other >>= 1;
// }
// return res;
// }// constexpr ll norm(ll num) const {
// if (num < 0) num += mod;
// if (num >= mod) num -= mod;
// return num;
// }// modint inv(){ return pow(mod - 2); }
// modint operator+(modint other){ return modint(num + other.num); }
// modint operator-(){ return { -num }; }
// modint operator-(modint other){ return modint(-other + *this); }
// modint operator*(modint other){ return modint(num * other.num); }
// modint operator/(modint other){ return *this * other.inv(); }
// modint &operator*=(modint other) { num = num * other.num % mod; return *this; }
// modint &operator+=(modint other) { num = norm(num + other.num); return *this; }
// modint &operator-=(modint other) { num = norm(num - other.num); return *this; }
// modint &operator/=(modint other) { return *this *= other.inv(); }
// friend istream& operator>>(istream& is, modint& other){ is >> other.num; other.num %= mod; return is; }
// friend ostream& operator<<(ostream& os, modint other){ other.num = (other.num + mod) % mod; return os << other.num; }
// };int n,k;
int a[200005];
int p[200005];
vector<PII>ans;
void icealsoheat(){cin>>n>>k;int bns=0;for(int i=1;i<=n;i++)cin>>a[i],p[a[i]]=i;for(int i=1;i<=n;i++){int id=p[i];int x=i;for(int j=i-1;j>=1;j--){if(p[j]>=id+k){// cout<<p[x]<<":::"<<p[j]<<"\n";ans.push_back({p[x],p[j]});a[id]=j;a[p[j]]=x;swap(p[x],p[j]);x=j;}}}cout<<ans.size()<<"\n";for(auto [i,j]:ans){cout<<i<<" "<<j<<"\n";}// for(int i=1;i<=n;i++){// cout<<a[i]<<" ";// }}
signed main(){ios::sync_with_stdio(false); //int128不能用快讀!!!!!!cin.tie();cout.tie();int _yq;_yq=1;// cin>>_yq;while(_yq--){icealsoheat();}
}
//
//??? ???????????
//????????????? ???????????
//??????????????????????????
//????????????????????? ?????
//???????????????????????
//??????????????????? ????
//????????????????????????
//????????????????????????
//???????????????????????
//??????????????????????
//??????????????
//????????????
//
C - Subsequence and Prefix Sum
C - Subsequence and Prefix Sum (atcoder.jp)
一道非常巧妙的dp題,他的狀態轉移非常的奇妙。
我們考慮前i位的數字對后面數字的貢獻值。可以分成兩種情況。
1.第i位數字沒有被選中
2.第i位數字被選中
當第i位數字被選中時,每一個位數i它所能合成的狀態數字都對后面i+1到n的數字有相應的貢獻。而這里面0的情況比較特殊,如果第i位的合成數字是0,其實不會改變下一個選中的數字。
這里面有一種情況比較特殊
例如1 -1 5 5 .........
這里我們會發現,我們選擇1和-1后,選擇第3個5和第4個5的情況是重復的,所以我們要想辦法將它去重。
#pragma GCC optimize(3) //O2優化開啟
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
// const int mod=1e9+7;
const int MX=0x3f3f3f3f3f3f3f3f;
//inline int read() //快讀
//{
// int xr=0,F=1; char cr;
// while(cr=getchar(),cr<'0'||cr>'9') if(cr=='-') F=-1;
// while(cr>='0'&&cr<='9')
// xr=(xr<<3)+(xr<<1)+(cr^48),cr=getchar();
// return xr*F;
//}
//void write(int x) //快寫
//{
// if(x<0) putchar('-'),x=-x;
// if(x>9) write(x/10); putchar(x%10+'0');
//}
// 比 unordered_map 更快的哈希表
// #include <ext/pb_ds/assoc_container.hpp>
// using namespace __gnu_pbds;
// const int RANDOM = chrono::high_resolution_clock::now().time_since_epoch().count();
// struct chash {
// int operator()(int x) const { return x ^ RANDOM; }
// };
// typedef gp_hash_table<int, int, chash> hash_t;
constexpr ll mod = 1e9 + 7; //此處為自動取模的數
class modint{ll num;
public:modint(ll num = 0) :num(num % mod){}ll val() const {return num;}modint pow(ll other) {modint res(1), temp = *this;while(other) {if(other & 1) res = res * temp;temp = temp * temp;other >>= 1;}return res;}constexpr ll norm(ll num) const {if (num < 0) num += mod;if (num >= mod) num -= mod;return num;}modint inv(){ return pow(mod - 2); }modint operator+(modint other){ return modint(num + other.num); }modint operator-(){ return { -num }; }modint operator-(modint other){ return modint(-other + *this); }modint operator*(modint other){ return modint(num * other.num); }modint operator/(modint other){ return *this * other.inv(); }modint &operator*=(modint other) { num = num * other.num % mod; return *this; }modint &operator+=(modint other) { num = norm(num + other.num); return *this; }modint &operator-=(modint other) { num = norm(num - other.num); return *this; }modint &operator/=(modint other) { return *this *= other.inv(); }friend istream& operator>>(istream& is, modint& other){ is >> other.num; other.num %= mod; return is; }friend ostream& operator<<(ostream& os, modint other){ other.num = (other.num + mod) % mod; return os << other.num; }
};int n,k;
int a[500005];
modint dp[105][5005];
modint sum[5005];
void icealsoheat(){cin>>n;for(int i=0;i<=20;i++)if(i!=10)sum[i]=1;for(int i=1;i<=n;i++)cin>>a[i];modint ans=1;for(int i=0;i<n;i++){dp[i][a[i]+1000]=dp[i][a[i]+1000]+sum[a[i]+10];sum[a[i]+10]=0;for(int j=0;j<=2000;j++){if(j==1000)continue;for(int o=i+1;o<=n;o++){// if(j+a[o]<0)cout<<"+++\n";if(j+a[o]<0)continue;dp[o][j+a[o]]+=dp[i][j];ans+=dp[i][j];}}for(int j=0;j<=20;j++){if(j!=10)sum[j]+=dp[i][1000];}}cout<<dp[2][1]<<"+++\n";cout<<ans;}
signed main(){ios::sync_with_stdio(false); //int128不能用快讀!!!!!!cin.tie();cout.tie();int _yq;_yq=1;// cin>>_yq;while(_yq--){icealsoheat();}
}
//
//??? ???????????
//????????????? ???????????
//??????????????????????????
//????????????????????? ?????
//???????????????????????
//??????????????????? ????
//????????????????????????
//????????????????????????
//???????????????????????
//??????????????????????
//??????????????
//????????????
//