题做得有点懵B,过来写个题解吧...
T1
我只能说思(ji)路(qi)奇(gou)妙(shi)
强制在线就是tmd个幌子
其实是根据las=0 OR 质数,然后反解出opt(神神神%%%)
除了最后一个操作是 询问需要暴力sort外,其他都是推出来的
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
using namespace std;
const int N=200006;
const int MAXVAL=1000006;
int prime[MAXVAL],cnt;
bool he[MAXVAL];
void get_prime()
{
for(int i=2;i<MAXVAL;++i)
{
if(!he[i])
prime[++cnt]=i;
for(int j=1;j<=cnt&&prime[j]*i<MAXVAL;++j)
{
he[prime[j]*i]=1;
if(i%prime[j]==0)
break;
}
}
}
struct son
{
int op,l,r;
}ji[N];
int an[N],kk[N];
int n,m,K;
int v[N];
void work()
{
int order=m,flag=0;
if(kk[m]==1)
{
flag=1;
--order;
}
for(int i=order;i>=1;--i)
if(kk[i]==1)
an[i]=kk[i+1]^ji[i+1].op;
if(flag)
{
int tin1,tin2,las=0;
for(int i=1;i<m;++i)
{
if( kk[i]==2 )
{
tin1=ji[i].l^las;
tin2=ji[i].r^las;
v[tin1]=tin2;
}
else
las=an[i];
}
tin1=las^ji[m].l;
tin2=las^ji[m].r;
sort(v+tin1,v+tin2+1);
int con=0;
for(int i=tin1;i<=tin2;++i)
if(!he[v[i]])
{
++con;
if(con==K)
{
an[m]=v[i];
break;
}
}
}
for(int i=1;i<=m;++i)
if(kk[i]==1)
printf("%d
",an[i]);
}
int main(){
get_prime();
scanf("%d%d%d",&n,&K,&m);
for(int i=1;i<=n;++i)
scanf("%d",&v[i]);
for(int i=1;i<=m;++i)
scanf("%d%d%d",&ji[i].op,&ji[i].l,&ji[i].r);
int las=0;
for(int i=1;i<=m;++i)
{
if( (las^ji[i].op)&1 )
{
kk[i]=1;
las=1;
}
else
kk[i]=2;
}
work();
}
T2
n^3暴力好打
30分,开O3 40分...
正解就是枚举左(或上)边界,算出右边界在最右面的ans,然后再扫右边界,一个一个的去(用链表维护...)
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <vector>
#include <algorithm>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int N=3106;
int tx[N],ty[N],id[N];
int dui[N];
int con;
int R,C,n,K;
int jix[N],jiy[N];
ll ans,sum;
int pre[N],nxt[N];
ll v[N];
bool ok(int x,int y)
{
/*if(tx[id[x]]==tx[id[y]])
return ty[id[x]]<ty[id[y]];
return tx[id[x]]<tx[id[y]];*/
if(tx[x]==tx[y])
return ty[x]<ty[y];
return tx[x]<tx[y];
}
vector<int> q[N];
void del(int x)
{
nxt[pre[x]]=nxt[x];
pre[nxt[x]]=pre[x];
sum-=v[x];
int t1=nxt[x],t2=nxt[x];
for(int i=1;i<K;++i)
t2=nxt[t2];
for(int i=1;i<=K;++i)
{
sum-=v[t1];
v[t1]=(tx[t1]-tx[pre[t1]])*(R-tx[t2]+1);
sum+=v[t1];
t1=pre[t1];t2=pre[t2];
}
}
void work()
{
ll temp;
int nx;
for(int j=1;j<=C;++j)
{
sum=0;con=0;mem(v,0);
for(int i=1;i<=10;++i)
{
tx[++con]=0;
ty[con]=0;
tx[++con]=R+1;
ty[con]=0;
}
for(int i=1;i<=n;++i)
if(jiy[i]>=j)
{
tx[++con]=jix[i];
ty[con]=jiy[i];
dui[i]=con;
}
for(int i=1;i<=con;++i)id[i]=i;
sort(id+1,id+1+con,ok);
for(int i=1;i<=con;++i)
pre[id[i]]=id[i-1],nxt[id[i]]=id[i+1];
pre[id[1]]=id[1];nxt[id[con]]=id[con];
//printf("con=%d
",con);
/*for(int qw=id[1],i=1;i<=con;++i,qw=nxt[qw])
printf("%d %d
",tx[qw],ty[qw]);
printf("
");*/
for(int i=1;i<=con;++i)
{
nx=i;
for(int k=1;k<K;++k)
nx=nxt[nx];
//printf("%d %d %d %d
",tx[id[i]],ty[id[i]],tx[nx],ty[nx]);
v[i]=(tx[i]-tx[pre[i]])*(R-tx[nx]+1);
sum+=v[i];
//printf("sum=%lld
",sum);
}
//printf("sum=%lld
",sum);
for(int k=C;k>=j;--k)
{
//printf("k=%d sum=%lld
",k,sum);
ans+=sum;
temp=q[k].size();
for(int p=0;p<temp;++p)
del(dui[q[k][p]]);
}
//printf("j=%d ans=%lld
",j,ans);
}
}
int main(){
//freopen("in.in","r",stdin);
//freopen("T2.in","r",stdin);
//freopen("T22.out","w",stdout);
scanf("%d%d%d%d",&R,&C,&n,&K);
for(int i=1;i<=n;++i)
{
scanf("%d%d",&jix[i],&jiy[i]);
q[jiy[i]].push_back(i);
}
work();
cout<<ans;
}
总之 这次题及其 啊啊啊啊,然后就觉得自己弱的 ...