QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#51502 | #1443. Potato Shuffle | Jayfeather233 | WA | 2ms | 3856kb | C++ | 4.0kb | 2022-10-02 15:41:00 | 2022-10-02 15:41:04 |
Judging History
answer
#include <iostream>
#include <cstdio>
#include <algorithm>
const int MOD = 1e9+7;
int fast_pow(int a,int b){
int ans=1;
while(b){
if(b&1) ans=(1ll*ans*a)%MOD;
a=(1ll*a*a)%MOD;
b>>=1;
}
return ans;
}
#define ls (u<<1)
#define rs ((u<<1)+1)
#define MAXN 100100
namespace maxtree{
int maxn[MAXN<<2];
void build(int* s, int u, int l, int r){
if(l==r){
maxn[u]=s[l];
return;
}
int mid=(l+r)>>1;
build(s,ls,l,mid);
build(s,rs,mid+1,r);
maxn[u]=std::max(maxn[ls],maxn[rs]);
}
int ask(int u, int l, int r, int ll, int rr){
if(ll<=l&&r<=rr) return maxn[u];
if(rr<l || r<ll) return 0;
int mid=(l+r)>>1;
return std::max(ask(ls,l,mid,ll,rr),ask(rs,mid+1,r,ll,rr));
}
}
namespace sizetree{
int sz[MAXN<<2];
void build(int u, int l, int r){
if(l==r){
sz[u]=1;
return;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
sz[u]=sz[ls]+sz[rs];
}
int ask(int u, int l, int r, int ll, int rr){
if(ll<=l&&r<=rr) return sz[u];
if(rr<l || r<ll) return 0;
int mid=(l+r)>>1;
return ask(ls,l,mid,ll,rr)+ask(rs,mid+1,r,ll,rr);
}
void modify(int u,int l,int r,int x){
//printf("mdy at %d %d %d %d\n",u,l,r,x);
if(x<l || r<x) return;
if(l==r){
sz[u]=0;
return;
}
int mid=(l+r)>>1;
modify(ls,l,mid,x);
modify(rs,mid+1,r,x);
sz[u]=sz[ls]+sz[rs];
}
void opt(int u,int l,int r){
printf("%d: %d %d %d\n",u,l,r,sz[u]);
if(l==r) return;
int mid=(l+r)>>1;
opt(ls,l,mid);
opt(rs,mid+1,r);
}
}
#undef ls
#undef rs
namespace link{
struct point{
int pos,nxt,pre;
}s[MAXN];
int head[MAXN],ls=1;
void add(int u,int p){//add a integer[u] at position[p]
s[ls].pos=p;
s[ls].nxt=head[u];
s[head[u]].pre=ls;
head[u]=ls++;
}//reverse
}
using namespace std;
int n,k;
int disc_mp[100100];
int ny[100100];
int after_disc[100100];
int find_next_max(int l,int r){
return maxtree::ask(1,1,n,l,r);
}
int C(int n,int m){//choose m from tot n
int ans=1;
for(int i=1;i<=m;i++){
ans=(1ll*ans*ny[i])%MOD;
ans=(1ll*ans*(n-i+1))%MOD;
}
return ans;
}
int tot;
int work(int l,int r,int minn){
int maxn=find_next_max(l,r);
//if(maxn-k<minn) return 1;
if(maxn<minn || r<=l) return 1;
//printf("AT %d %d %d %d\n",l,r,maxn,minn);
int tot_sz=sizetree::ask(1,1,n,l,r);
int bel=0;
for(int t=minn;disc_mp[t]<=k-disc_mp[maxn]&&t<=tot;t++){
//printf(" disc:t=%d\n",t);
for(int i=link::head[t];i;i=link::s[i].nxt){
if(r<link::s[i].pos) break;
if(link::s[i].pos<l) continue;
bel++;
if(!link::s[i].pre){
link::head[t]=link::s[i].nxt;
link::s[link::s[i].nxt].pre=0;
}else{
link::s[link::s[i].pre].nxt=link::s[i].nxt;
link::s[link::s[i].nxt].pre=link::s[i].pre;
}
sizetree::modify(1,1,n,link::s[i].pos);
//sizetree::opt(1,1,n);
//printf(" modify:%d\n",link::s[i].pos);
}
minn=max(minn,t);
}
//printf(" size:%d bel:%d\n",tot_sz,bel);
int ans=C(tot_sz,bel);
for(int i=link::head[maxn];i;i=link::s[i].nxt){
ans=(1ll*ans*work(l,link::s[i].pos-1,minn+1))%MOD;
l=link::s[i].pos+1;
}
ans=(1ll*ans*work(l,r,minn+1))%MOD;
return ans;
}
struct tt{
int v,pos;
}disc[100100];
int operator < (const tt a,const tt b){
return a.v==b.v ? a.pos>b.pos : a.v<b.v;
}
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++) ny[i]=fast_pow(i,MOD-2);
for(int i=0;i<n;i++){
scanf("%d",&disc[i].v);
disc[i].pos=i;
}
sort(disc,disc+n);
for(int i=1;i<n;i++){
if(disc[i].v!=disc[i-1].v){
disc_mp[tot]=disc[i-1].v;
disc[i-1].v=tot;
tot++;
}else{
disc_mp[tot]=disc[i-1].v;
disc[i-1].v=tot;
}
}
disc_mp[tot]=disc[n-1].v;
disc[n-1].v=tot;
//for(int i=0;i<=tot;i++) printf("mp:%d->%d\n",i,disc_mp[i]);
for(int i=0;i<n;i++){
after_disc[disc[i].pos+1]=disc[i].v;
}
//for(int i=1;i<=n;i++){
// printf("%d ",after_disc[i]);
//}
//printf("\n");
maxtree::build(after_disc,1,1,n);
sizetree::build(1,1,n);
for(int i=n;i>=1;i--){
link::add(after_disc[i],i);
}
printf("%d",work(1,n,0));
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 2ms
memory: 3744kb
input:
3 7 5 2 4
output:
3
result:
ok "3"
Test #2:
score: 0
Accepted
time: 2ms
memory: 3856kb
input:
5 4 1 2 3 2 1
output:
10
result:
ok "10"
Test #3:
score: 0
Accepted
time: 2ms
memory: 3680kb
input:
6 4 9 10 1 9 8 9
output:
1
result:
ok "1"
Test #4:
score: 0
Accepted
time: 2ms
memory: 3828kb
input:
8 0 4 9 2 9 2 3 9 10
output:
1
result:
ok "1"
Test #5:
score: 0
Accepted
time: 2ms
memory: 3748kb
input:
5 3 9 8 1 9 8
output:
1
result:
ok "1"
Test #6:
score: -100
Wrong Answer
time: 2ms
memory: 3808kb
input:
6 12 4 7 2 9 1 9
output:
30
result:
wrong answer 1st words differ - expected: '60', found: '30'