A: Rikka和Galgame
不会待补
B: 假装是区间众数
思路:莫队算法,离线给所有区间排序,然后按顺序求答案即可,复杂度n^1.5
// res[ i ]=x 含义为有x个数出现了 i 次
#include
#define db double
using namespace std;
const int maxn=1e5+10;
int a[maxn],b[maxn],vis[maxn],ans[maxn],block;
int res[maxn],mx;
struct node
{
int l,r,id;
bool operator<(const node&t)const
{
if(l/block==t.l/block)
return r=c[i].l;j--)
up(j,1);
for(int j=q+1;j<=c[i].r;j++)
up(j,1);
for(int j=q;j>c[i].r;j--)
up(j,-1);
ans[c[i].id]=mx;
p=c[i].l,q=c[i].r;
}
for(int i=1;i<=Q;i++)
printf("%d\n",ans[i]);
}
C: 上杉绘梨衣的告别(一)——时光南站
思路:暴力枚举len即可(每0.5枚举一次),然后用二分查找出最近的算答案即可,复杂度len*m*log(n)
#include
#define db double
using namespace std;
const int maxn=1e5+10;
int p[305],d[305],len,m,n;
db ans,pos,b[305];
void ss(db xx)
{
for(int i=1;i<=n;i++)
b[i]=d[i]+xx;
db res=0;
for(int i=1;i<=m;i++)
{
int x=lower_bound(b+1,b+1+n,p[i])-b;
if(x>n)x--;
else if(x==0)x++;
db tmp=fabs(b[x]-p[i]);
if(b[x]>p[i])
{
if(x!=1)
tmp=min(tmp,fabs(b[x-1]-p[i]));
}
else if(b[x]ans)ans=res,pos=xx;
}
int main()
{
while(cin>>len)
{
cin>>m;
for(int i=1;i<=m;i++)
cin>>p[i];
cin>>n;
for(int i=2;i<=n;i++)
cin>>d[i];
ans=0,pos=0;
for(int i=0;i<=len-d[n];i++)
{
ss(i);
if(i!=len-d[n])
ss(0.5+i);
}
printf("%.3lf %.3f\n",pos,ans);
}
}
D: 上杉绘梨衣的告别(二)——项链
不会待补
E: 喜闻乐见的逆序对
思路:重点讲这题(其实很水的),举个例子,五个数:1 2 3 4 5,贡献分别为 3 2 0 0 0,我先从大到小枚举这5个数,5的贡献是0,从空集插入一个5,4的贡献也为0,那么4就插到集合第0个数的后面,集合有两个数 4->5,3同理,插入后 3->4->5,接下来2的贡献为2,那么显然把2插入集合第二个数的后面,即3->4->2->5,1就插入到第三个数的后面,所以答案是 3 4 2 1 5。
ok,思路是不是很清晰了?不过还是没有完全解决这个问题,普通插入n*n的复杂度肯定不行,动态插入怎么搞?这时就要献出treap了(不会可以先学,顺便a了这个题,这题用到的treap十分简单),完美的用n*logn复杂度解决掉动态插入问题。
#include
using namespace std;
const int maxn=1e5+10;
struct node
{
int num,v;
bool operator<(const node&t)const
{
return num>t.num;
}
}a[maxn];
int cnt,ans[maxn];
struct Node *null;
struct Node
{
Node *ch[2];
int r;
int v;
int s;
Node(int v):v(v){ch[0]=ch[1]=null;r=rand();s=1;}
void maintain()
{
s=1;
s+=ch[0]->s;
s+=ch[1]->s;
}
};
void rotate(Node* &o,int d)
{
Node *k=o->ch[d^1];o->ch[d^1]=k->ch[d];
k->ch[d]=o;o->maintain();k->maintain();
o=k;
}
void insert(Node* &o,int x,int k)
{
if(o==null) o=new Node(x);
else
{
int d=(k<=(o->ch[0]->s)?0:1);
if(d==1)k=k-o->ch[0]->s-1;
insert(o->ch[d],x,k);
if(o->ch[d]->r>o->r)rotate(o,d^1);
}
o->maintain();
}
void dfs(Node* o)
{
if(o==null)return;
dfs(o->ch[0]);
ans[++cnt]=o->v;
dfs(o->ch[1]);
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i].num);
for(int i=1;i<=n;i++)
scanf("%d",&a[i].v);
sort(a+1,a+1+n);
null=new Node(0);
null->s=0;
Node *root=null;
for(int i=1;i<=n;i++)
insert(root,a[i].num,a[i].v);
dfs(root);
for(int i=1;i