赛时AKAK还是写div4爽
C:直接看总和是不是个完全平方数即可
因为S=a*a,总和是S
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+10,mod=998244353;
#define int long long
typedef long long LL;
typedef pair<int, int> PII;
typedef unsigned long long ULL;
const long long inf=1e17;
using node=tuple<int,int,int>;
int n,m,k;
int a[N];
void solve()
{
cin>>n;
int res=0;
for(int i=1;i<=n;i++){
int x;cin>>x;
res+=x;
}
if((int)sqrt(res)*(int)sqrt(res)==res)
{
cout<<"YES\n";
}else cout<<"NO\n";
}
signed main()
{
cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
int t=1;
cin>>t;
while(t--) solve();
}
D:
我写了个dp
f状态是
前i个字母能不能分成合法序列,0是不能,1是能
再拿个lst数组记录当前点由哪些转移过来的即可
然后记录哪些点后面该用.
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+10,mod=998244353;
#define int long long
typedef long long LL;
typedef pair<int, int> PII;
typedef unsigned long long ULL;
const long long inf=1e17;
using node=tuple<int,int,int>;
int n,m,k;
int a[N];
void solve()
{
cin>>n;
string s;
cin>>s;
s="?"+s;
vector<int> f(n+10);
vector<int> lst(n+10,0);
f[0]=1;
set<char> st1,st2;
st1.insert('a');
st1.insert('e');
st2.insert('b');
st2.insert('c');
st2.insert('d');
for(int i=1;i<=n;i++)
{
if(i>=2){
if(st2.count(s[i-1])&&st1.count(s[i])){
f[i]|=f[i-2];
if(f[i-2]==1) lst[i]=i-2;
}
}
if(i>=3)
{
if(st2.count(s[i-2])&&st1.count(s[i-1])&&st2.count(s[i])){
f[i]|=f[i-3];
if(f[i-3]==1) lst[i]=i-3;
}
}
}
vector<bool> st(n+10);
int x=n;
//cout<<f[n]<<"\n";
while(x>=1)
{
x=lst[x];
st[x]=true;
// cout<<x<<"\n";
}
for(int i=1;i<=n;i++){
cout<<s[i];
if(st[i]) cout<<".";
}
cout<<"\n";
}
signed main()
{
cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
int t=1;
cin>>t;
while(t--) solve();
}
E:
因为是连续区间问题
求[l,r]的偶数位,奇数位的差,是否等于0
转化成前缀和,变成是否有两个点s[i]-s[j-1]==0
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+10,mod=998244353;
#define int long long
typedef long long LL;
typedef pair<int, int> PII;
typedef unsigned long long ULL;
const long long inf=1e17;
using node=tuple<int,int,int>;
int n,m,k;
int a[N];
void solve()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
vector<int> s(n+10);
for(int i=1;i<=n;i++){
if(i&1) s[i]=s[i-1]+a[i];
else s[i]=s[i-1]-a[i];
}
bool ok=false;
map<int,int> mp;
mp[0]++;
for(int i=1;i<=n;i++){
if(mp.count(s[i])){
cout<<"YES\n";return ;
}
mp[s[i]]++;
}
cout<<"NO\n";
}
signed main()
{
cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
int t=1;
cin>>t;
while(t--) solve();
}
F:
想一个区间有哪些区间合法
比如[1,5]
有哪些区间合法
[2,3] [2,4]
[3,4]
因为每个点都不同
所以要满足
其他区间被这个区间包含
当前区间是 l[i] r[i]
满足的区间需要满足
l[j]>=l[i]&&r[i]>=r[j]
我们排序左端点,然后用树状数组统计右端点即可,
因为坐标很大,我们要离散化全部点
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+10,mod=998244353;
#define int long long
typedef long long LL;
typedef pair<int, int> PII;
typedef unsigned long long ULL;
const long long inf=1e17;
using node=tuple<int,int,int>;
int n,m,k;
class BitTree {
public:
vector<int> tree;
int n;
BitTree(int _n) : n(_n) {
tree.resize(n+1);
fill(tree.begin(),tree.end(),0);
}
inline int lowbit(int x) { return x&-x; }
inline void Modify(int x,int v) {
for(;x<=n;x+=lowbit(x)) tree[x]+=v;
}
inline int q(int x) {
int ret=0;
if(x<=0) return 0;
for(;x;x-=lowbit(x)) ret+=tree[x];
return ret;
}
inline int Query(int l,int r) {
return q(r)-q(l-1);
}
};
PII a[N];
vector<int> num;
int find(int x){
return lower_bound(num.begin(),num.end(),x)-num.begin()+1;
}
void solve()
{
cin>>n;
num.clear();
for(int i=1;i<=n;i++) cin>>a[i].first>>a[i].second;
for(int i=1;i<=n;i++){
num.push_back(a[i].second);
num.push_back(a[i].first);
}
sort(num.begin(),num.end());
sort(a+1,a+1+n);
int res=0;
BitTree tr(2*n+10);
for(int i=1;i<=n;i++) tr.Modify(find(a[i].second),1);
for(int i=1;i<=n;i++){
tr.Modify(find(a[i].second),-1);
res+=tr.Query(find(a[i].first),find(a[i].second));
}
cout<<res<<"\n";
}
signed main()
{
cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
int t=1;
cin>>t;
while(t--) solve();
}
G:
范围n=1000,s=1000
我们不妨设状态有两个
[第几个点][速度]
一共有1000*1000个不同的状态
跑个dijksta即可
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+10,mod=998244353;
#define int long long
typedef long long LL;
typedef pair<int, int> PII;
typedef unsigned long long ULL;
const long long inf=1e17;
using node=tuple<int,int,int>;
int n,m,k;
vector<PII> g[N];
int a[N];
void solve()
{
cin>>n>>m;
for(int i=1;i<=n;i++) g[i].clear();
for(int i=1;i<=m;i++){
int a,b,c;
cin>>a>>b>>c;
g[a].push_back({b,c});
g[b].push_back({a,c});
}
for(int i=1;i<=n;i++) cin>>a[i];
vector<vector<int>> dist(n+10,vector<int>(1010,1e18));
priority_queue<node,vector<node>,greater<node>> q;
vector<vector<bool>> st(n+10,vector<bool>(1010,false));
q.emplace(0,a[1],1);
dist[1][a[1]]=0;
while(q.size())
{
auto [dd,s,t]=q.top();
q.pop();
if(st[t][s]) continue;
st[t][s]=true;
for(auto [j,w]:g[t])
{
if(dist[j][min(s,a[j])]>dist[t][s]+w*s)
{
dist[j][min(s,a[j])]=dist[t][s]+w*s;
q.emplace(dist[j][min(s,a[j])],min(s,a[j]),j);
}
}
}
int res=2e18;
for(int i=1;i<=1000;i++) res=min(res,dist[n][i]);
cout<<res<<"\n";
}
signed main()
{
cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
int t=1;
cin>>t;
while(t--) solve();
}