A:
初看没啥思路,但是这个数据范围出奇的小;
其实这道题让我们觉得困难的原因是因为它有两个变量,如果变成仅对一个变量求最小值,这其实就是一个简单的完全背包问题;
因为M<=1000,val<=200,所以最终每个元素和的可能取值不会超过200 000,
考虑对于每一种存在的a的和的取值,求出它的b的和的最小值,然后对二者乘积找最小值;
code:
#include<bits/stdc++.h>
#define int long long
#define inf 0x3f3f3f3f3f3f3f
#define GG ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define cnot cout<<"NO"<<"\n"
#define cyes cout<<"YES"<<"\n"
#define cans cout<<ans<<"\n"
#define pb push_back
#define x0 first
#define y0 second
#define lc p<<1
#define rc p<<1|1
#define mem(a,b) memset(a,b,sizeof(a))
#define sp(x) fixed<<setprecision(x)
#define all(v) v.begin(),v.end()
#define fr(i,st,ed) for(int i=st;i<=ed;i++)
#define ffr(i,st,ed,dt) for(int i=st;i<=ed;i+=dt)
using namespace std;
typedef pair<int,string>Pis;
typedef pair<int,int>Pii;
typedef pair<string,string>Pss;
//const int N=1000*200+5,mod=1e9+7,M=1e6+10;
int lowbit(int x){
return x&(-x);}
void solve(){
int n,m;
cin>>n>>m;
vector<int>u(m+1),v(m+1),a(m+1),b(m+1);
fr(i,1,m){
cin>>u[i]>>v[i]>>a[i]>>b[i];
}
//dp[point][costa]=mincostb
int N=200*m+5;
vector<vector<int>>dp(n+1,vector<int>(N,inf));
dp[1][0]=0;
fr(C,1,N-1){
fr(i,1,m){
if(C>=a[i]){
dp[v[i]][C]=min(dp[v[i]][C],dp[u[i]][C-a[i]]+b[i]);
}
}
}
int minx=inf;
int ans1=0;
int ans2=0;
fr(i,1,N-1){
if(dp[n][i]!=inf){
if(dp[n][i]*i<minx){
minx=dp[n][i]*i;
ans1=i;
ans2=dp[n][i];
}
}
}
cout<<ans1<<" "<<ans2<<"\n";
}
signed main(){
GG;
int _t=1;
cin>>_t;
while(_t--){
solve();
}
}
F
2026蓝桥省B LQ序列 原题
将每个问号同时看成1,0,统计1的前缀/0的后缀
对于每个?,比较前后缀大小,确定该点为0/1的贡献大
code:
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f3f3f3f
#define GG ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define cnot cout<<"NO"<<"\n"
#define cyes cout<<"YES"<<"\n"
#define cans cout<<ans<<"\n"
#define pb push_back
#define x0 first
#define y0 second
#define lc p<<1
#define rc p<<1|1
#define mem(a,b) memset(a,b,sizeof(a))
#define sp(x) fixed<<setprecision(x)
#define all(v) v.begin(),v.end()
#define fr(i,st,ed) for(int i=st;i<=ed;i++)
#define ffr(i,st,ed,dt) for(int i=st;i<=ed;i+=dt)
using namespace std;
typedef pair<int,string>Pis;
typedef pair<int,int>Pii;
typedef pair<string,string>Pss;
const int N=2e4+10,mod=1e9+7,M=1e6+10;
int lowbit(int x){
return x&(-x);}
void solve(){
int n;
cin>>n;
string s;
cin>>s;
s=" "+s;
vector<int>pl(n+5),eq(n+5),c(n+5),pre(n+5),ed(n+5);
for(int i=1;i<=n;i++){
if(s[i]=='1'||s[i]=='?')pl[i]=pl[i-1]+1;
else pl[i]=pl[i-1];
}
for(int i=n;i>=1;i--){
if(s[i]=='0'||s[i]=='?')eq[i]=eq[i+1]+1;
else eq[i]=eq[i+1];
}
for(int i=1;i<=n;i++){
if(s[i]=='1')c[i]=0;
else if(s[i]=='0')c[i]=1;
else{
if(pl[i]<eq[i])c[i]=0;
else c[i]=1;
}
}
ll ans=0;
ll cnt=0;
for(int i=1;i<=n;i++){
if(c[i]==0)pre[i]=pre[i-1]+1;
else pre[i]=pre[i-1];
}
for(int i=1;i<=n;i++){
if(c[i]==1){
ans+=pre[i];
}
}
cout<<ans<<"\n";
}
int main(){
GG;
int _t=1;
cin>>_t;
while(_t--){
solve();
}
}
H:
注意下如果共线且距离<=2,需要两次移动来抵消共线方向的偏移;
code:
#include<bits/stdc++.h>
#define int long long
#define inf 0x3f3f3f3f3f3f3f
#define GG ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define cnot cout<<"NO"<<"\n"
#define cyes cout<<"YES"<<"\n"
#define cans cout<<ans<<"\n"
#define pb push_back
#define x0 first
#define y0 second
#define lc p<<1
#define rc p<<1|1
#define mem(a,b) memset(a,b,sizeof(a))
#define sp(x) fixed<<setprecision(x)
#define all(v) v.begin(),v.end()
#define fr(i,st,ed) for(int i=st;i<=ed;i++)
#define ffr(i,st,ed,dt) for(int i=st;i<=ed;i+=dt)
using namespace std;
typedef pair<int,string>Pis;
typedef pair<int,int>Pii;
typedef pair<string,string>Pss;
const int N=2e4+10,mod=1e9+7,M=1e6+10;
int lowbit(int x){
return x&(-x);}
void solve(){
int x,y,X,Y;
cin>>x>>y>>X>>Y;
int dt1=abs(X-x);
int dt2=abs(Y-y);
int dt=max(dt1,dt2);
if(dt1==0&&dt2==0){
cout<<0<<"\n";
return;
}
else if(dt1==0||dt2==0){
if(dt<=2){
cout<<2<<"\n";
return;
}
}
cout<<(dt+1)/2<<"\n";
}
signed main(){
GG;
int _t=1;
cin>>_t;
while(_t--){
solve();
}
}
I
字典树模板,反转插入看有多少节点即可
code:
#include<bits/stdc++.h>
#define int long long
#define inf 0x3f3f3f3f3f3f3f
#define GG ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define cnot cout<<"NO"<<"\n"
#define cyes cout<<"YES"<<"\n"
#define cans cout<<ans<<"\n"
#define pb push_back
#define x0 first
#define y0 second
#define lc p<<1
#define rc p<<1|1
#define mem(a,b) memset(a,b,sizeof(a))
#define sp(x) fixed<<setprecision(x)
#define all(v) v.begin(),v.end()
#define fr(i,st,ed) for(int i=st;i<=ed;i++)
#define ffr(i,st,ed,dt) for(int i=st;i<=ed;i+=dt)
using namespace std;
typedef pair<int,string>Pis;
typedef pair<int,int>Pii;
typedef pair<string,string>Pss;
const int N=3e5+10,mod=1e9+7,M=1e6+10;
int lowbit(int x){
return x&(-x);}
int idx=0;
int son[N][26];
int cnt[N];
int n;
void ist(string s){
int p=0;
int sz=s.size();
fr(i,0,sz-1){
int u=s[i]-'a';
if(!son[p][u]){
son[p][u]=++idx;
}
p=son[p][u];
}
cnt[p]++;
}
void solve(){
cin>>n;
fr(i,1,n){
string s;
cin>>s;
reverse(all(s));
ist(s);
}
cout<<idx<<"\n";
}
signed main(){
GG;
int _t=1;
//cin>>_t;
while(_t--){
solve();
}
}
J
target string SCCPC;
我们不妨统计中间的C,看有多少条路径以它为中心
记录每一个C有多少个S与它相连;
记录每一个P有多少C与它相连;
那么对于每一个C, 搜索与它之间相邻的点,是c则统计相邻S的个数,是p则统计相邻c个数,-1(去掉自己);
相乘
code:
#include<bits/stdc++.h>
#define int long long
#define inf 0x3f3f3f3f3f3f3f
#define GG ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define cnot cout<<"NO"<<"\n"
#define cyes cout<<"YES"<<"\n"
#define cans cout<<ans<<"\n"
#define pb push_back
#define x0 first
#define y0 second
#define lc p<<1
#define rc p<<1|1
#define mem(a,b) memset(a,b,sizeof(a))
#define sp(x) fixed<<setprecision(x)
#define all(v) v.begin(),v.end()
#define fr(i,st,ed) for(int i=st;i<=ed;i++)
#define ffr(i,st,ed,dt) for(int i=st;i<=ed;i+=dt)
using namespace std;
typedef pair<int,string>Pis;
typedef pair<int,int>Pii;
typedef pair<string,string>Pss;
const int N=2e4+10,mod=1e9+7,M=1e6+10;
int lowbit(int x){
return x&(-x);}
//tag:sccpc
// num1 c-s
// num2 p-c
//(s)c<-c->p(c)
void solve(){
int n;
cin>>n;
vector<char>c(n+1);
vector<int>num1(n+1),num2(n+1);
vector<vector<int>>g(n+1);
fr(i,1,n){
cin>>c[i];
}
fr(i,1,n-1){
int u,v;
cin>>u>>v;
if(c[u]=='C'){
if(c[v]=='S'){
num1[u]++;
}
}
if(c[v]=='C'){
if(c[u]=='S'){
num1[v]++;
}
}
if(c[u]=='P'){
if(c[v]=='C'){
num2[u]++;
}
}
if(c[v]=='P'){
if(c[u]=='C'){
num2[v]++;
}
}
g[u].pb(v);
g[v].pb(u);
}
int ans=0;
fr(u,1,n){
int ans1=0;
int ans2=0;
if(c[u]=='C'){
for(int v:g[u]){
if(c[v]=='C'){
ans1+=num1[v];
}
if(c[v]=='P'){
ans2+=(num2[v]-1);
}
}
}
ans=ans+ans1*ans2;
}
cans;
}
signed main(){
GG;
int _t=1;
cin>>_t;
while(_t--){
solve();
}
}
K
队友敲的
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
#define endl "\n"
LL mod=998244353;
LL ksm(LL a,LL n){
LL res=1;
while(n){
if(n&1)res=res*a;
a=a*a;
n/=2;
}
return res;
}
vector<LL>fa(1e6),p(1e6),idx(1e6);
LL find(LL x){
if(x!=fa[x]){
fa[x]=find(fa[x]);
}
return fa[x];
}
void union1(LL x,LL y){
LL a=find(x),b=find(y);
if(idx[a]>idx[b])swap(a,b);
fa[a]=fa[b];
}
void solve(){
LL n;
cin>>n;
//vector<LL>p(n+1);
for(int i=1;i<=n;i++){
cin>>p[i];
idx[p[i]]=i;
fa[i]=i;
}
vector<vector<LL>>edag(n+1);
for(int i=1;i<n;i++){
LL u,v;
cin>>u>>v;
edag[u].push_back(v);
edag[v].push_back(u);
}
vector<LL>ans(n+1);
for(int i=n;i>=1;i--){
LL x=p[i];
for(int y:edag[x]){
if(idx[x]<idx[y]){
LL a=find(y);
fa[a]=x;
ans[a]=x;
}
}
}
for(int i=1;i<=n;i++){
if(ans[i]==i)cout<<0<<" ";
else cout<<ans[i]<<" ";
}
cout<<endl;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
LL T=1;
cin>>T;
while(T--){
solve();
}
}