tg 11 题解
T1
单调栈维护每个数可以做最大值的区间范围
记当前点的左端点为\(s\),右端点为\(t\),位置为\(pos\)
当前点的贡献:\((pos-s+1)*(t-pos+1)\)
然后就大力离散化维护前缀和即可
我不会用std::unique就手写了
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int o=2e5+22;
int a[o],n,q,b[o],c[o],cnt;
char ch[o];
struct node{
int s,t;
int id,val,exp;
}p[o];
bool cmp(node a,node b){
return a.exp<b.exp;
}
void in(){
scanf("%lld%lld",&n,&q);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
}
void pre(){
deque<node>q;
for(int i=1;i<=n;i++){
while(!q.empty()&&a[q.front().id]<a[i]){
p[q.front().id].t=i-1;
q.pop_front();
}
p[i].id=i,p[i].s=q.empty()?1:q.front().id+1;
q.push_front(p[i]);
}
while(!q.empty()){
p[q.front().id].t=n;
q.pop_front();
}
for(int i=1;i<=n;i++){
p[i].val=(p[i].id-p[i].s+1)*(p[i].t-p[i].id+1);
// printf("i=%d p[i].s=%d p[i].t=%d p[i].val=%d\n",i,p[i].s,p[i].t,p[i].val);
p[i].exp=a[p[i].id];
}
sort(a+1,a+n+1),sort(p+1,p+n+1,cmp);
for(int i=1;i<=n;i++){
if(a[i]!=a[i-1]){
cnt++;
}
c[cnt]=a[i];
}
cnt=0;
for(int i=1;i<=n;i++){
if(p[i].exp!=p[i-1].exp){
cnt++;
b[cnt]+=b[cnt-1];
}
b[cnt]+=p[i].val;
// printf("i=%d cnt=%d b[cnt]=%d\n",i,cnt,b[cnt]);
}
}
void work(){
for(int i=1,x;i<=q;i++){
scanf("%s%lld",ch+1,&x);
int now=lower_bound(c+1,c+cnt+1,x)-c;
if(ch[1]=='>'){
if(now==cnt+1){
puts("0");
continue;
}
if(c[now]>x){
now--;
}
printf("%lld\n",b[cnt]-b[now]);
}
if(ch[1]=='='){
if(x!=c[now]){
puts("0");
continue;
}
printf("%lld\n",b[now]-b[now-1]);
}
if(ch[1]=='<'){
printf("%lld\n",b[now-1]);
}
}
}
signed main(){
in();
pre();
work();
return 0;
}
T2
一个离奇的东西就是这玩意用莫队
其实可以通过看部分分看出来正解是莫队
分析\(n,m\)的变化对于\(ans\)的贡献
语言难以描述我就直接代码块了
void up(int n,int m){
ans=(2*ans%Mod-C(n,m)%Mod+Mod)%Mod;
}
void down(int n,int m){
ans=(ans%Mod+C(n-1,m)%Mod)%Mod*qpow(2,Mod-2)%Mod;
}
void right(int n,int m){
ans=(ans%Mod+C(n,m+1)%Mod)%Mod;
}
void left(int n,int m){
ans=(ans%Mod-C(n,m)%Mod+Mod)%Mod;
}
于是剩下的就是莫队了
一些乱七八糟的分块和排序就不写了
T3
不会谁能不看题解切掉CF3000的题啊
T4
记\(f[i][j]\)为当前放了\(i\)个数,\(j\)个值符合要求的方案数
转移从2个方向转移
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int o=222222,mod=998244353;
int f[2222][2222],k,ans,n;
void in(){
scanf("%lld%lld",&n,&k);
}
void work(){
f[1][0]=1;
for(int i=2;i<=n;i++){
for(int j=0;j<=min(i/2,k);j++){
if(!j) {f[i][j]=(f[i-1][j]*(2*j+2)%mod)%mod;continue;}
f[i][j]=(f[i-1][j-1]*(i-2*j)%mod+f[i-1][j]*(2*j+2)%mod)%mod;
}
}
}
void out(){
ans=f[n][k];
printf("%lld\n",ans);
}
signed main(){
in();
work();
out();
}

浙公网安备 33010602011771号