Submission #16852
Source Code Expand
#include"training.h"
#include<cmath>
#include<cstdio>
#include<algorithm>
#define rep(i,n) for(int i=0;i<(n);i++)
using namespace std;
class Fenwick_tree{
int n,a[30000];
public:
void build(int n){
this->n=n;
rep(i,n) a[i]=0;
}
void add(int i,int v){
for(;i<n;i|=i+1) a[i]+=v;
}
int sum(int i,int j){
if(i==0){
int s=0;
for(;j>=0;j=(j&(j+1))-1) s+=a[j];
return s;
}
return sum(0,j)-sum(0,i-1);
}
};
class Fenwick_tree_dual{
int n,a[174];
public:
void build(int n){
this->n=n;
rep(i,n) a[i]=0;
}
void add(int i,int j,int v){
if(i==0){
for(;j>=0;j=(j&(j+1))-1) a[j]+=v;
return;
}
add(0,j,v);
add(0,i-1,-v);
}
int sum(int i){
int s=0;
for(;i<n;i|=i+1) s+=a[i];
return s;
}
};
class Fenwick_tree_dual_2D{
int m;
Fenwick_tree_dual a[174];
public:
void build(int m,int n){
this->m=m;
rep(i,m) a[i].build(n);
}
void add(int t,int l,int b,int r,int v){
if(t==0){
for(;b>=0;b=(b&(b+1))-1) a[b].add(l,r,v);
return;
}
add(0,l, b ,r, v);
add(0,l,t-1,r,-v);
}
int sum(int i,int j){
int s=0;
for(;i<m;i|=i+1) s+=a[i].sum(j);
return s;
}
};
int n,n2,a[30000];
Fenwick_tree_dual_2D block; // block[i][j] := ( バケット i の左端からバケット j の右端までの区間についての解 )
Fenwick_tree freq[174]; // freq[i] := ( バケット 0 の左端からバケット i の右端までの区間についての頻度分布 )
void init(int _n,int _a[]){
n=_n;
n2=(int)ceil(sqrt(n));
rep(i,n) a[i]=_a[i]-1;
// block の計算
block.build(n2,n2);
rep(i,n2){
static Fenwick_tree FT;
FT.build(n);
int res=0;
for(int j=n2*i;j<n;){
int i0=j/n2;
rep(k,n2){
if(j==n) break;
res+=FT.sum(a[j]+1,n-1);
FT.add(a[j],1);
j++;
}
block.add(i,i0,i,i0,res);
}
}
// freq の計算
static int tmp[30000];
for(int i=0;i<n;){
int i0=i/n2;
freq[i0].build(n);
rep(j,n2){
if(i==n) break;
tmp[a[i]]++;
i++;
}
rep(v,n) freq[i0].add(v,tmp[v]);
}
}
// 更新クエリ a[p] = x
void update(int p,int x){
x--;
if(a[p]==x) return;
int u=p/n2; // p が属するバケットの番号
// block の更新
// p より左の部分による block の変化分の計算
int m1=0,m2=0;
for(int i=n2*u;i<p;i++){
if(x< a[i] && a[i]<=a[p]) m1++;
if(x>=a[i] && a[i]> a[p]) m2++;
}
block.add(u,u,u,n2-1, m1);
block.add(u,u,u,n2-1,-m2);
for(int w=u-1;w>=0;w--){
if(x<a[p]) m1+=freq[w].sum(x+1,a[p])-(w>0?freq[w-1].sum(x+1,a[p]):0);
if(x>a[p]) m2+=freq[w].sum(a[p]+1,x)-(w>0?freq[w-1].sum(a[p]+1,x):0);
block.add(w,u,w,n2-1, m1);
block.add(w,u,w,n2-1,-m2);
}
// p より右の部分による block の変化分の計算
m1=m2=0;
for(int i=p+1;i<min(n2*(u+1),n);i++){
if(x> a[i] && a[i]>=a[p]) m1++;
if(x<=a[i] && a[i]< a[p]) m2++;
}
block.add(0,u,u,u, m1);
block.add(0,u,u,u,-m2);
for(int w=u+1;w<n2;w++){
if(x>a[p]) m1+=freq[w].sum(a[p],x-1)-freq[w-1].sum(a[p],x-1);
if(x<a[p]) m2+=freq[w].sum(x,a[p]-1)-freq[w-1].sum(x,a[p]-1);
block.add(0,w,u,w, m1);
block.add(0,w,u,w,-m2);
}
// freq の更新
for(int v=u;v<n2;v++){
freq[v].add(a[p],-1);
freq[v].add(x,1);
}
a[p]=x;
}
int train(int l,int r){
r++;
// u : [l, r) に含まれるバケットのうち、一番左にあるもの
// v : [l, r) の右にあるバケットのうち、一番左にあるもの
int u=l; if(u%n2!=0) u+=n2-l%n2; u/=n2;
int v=r/n2;
int res=0;
if(u<v){
// バケット内でのスワップ回数
res+=block.sum(u,v-1);
// 左にはみ出した部分とバケット内とのスワップ回数
for(int i=l;i<n2*u;i++){
res+=freq[v-1].sum(0,a[i]-1);
if(u>0){
res-=freq[u-1].sum(0,a[i]-1);
}
}
// 右にはみ出した部分とバケット内とのスワップ回数
for(int i=n2*v;i<r;i++){
res+=freq[v-1].sum(a[i]+1,n-1);
if(u>0){
res-=freq[u-1].sum(a[i]+1,n-1);
}
}
}
// 左にはみ出した部分と右にはみ出した部分とのスワップ回数
int m=0;
static int b[30000]; // はみ出した部分だけからなる a の部分列
if(u<v){
for(int i=l;i<n2*u;i++) b[m++]=a[i];
for(int i=n2*v;i<r;i++) b[m++]=a[i];
}
else{ // [l, r) がどのバケットも包含していないとき
for(int i=l;i<r;i++) b[m++]=a[i];
}
static Fenwick_tree FT;
FT.build(n);
rep(i,m){
res+=FT.sum(b[i]+1,n-1);
FT.add(b[i],1);
}
return res;
}
Submission Info
Submission Time
2012-05-23 05:45:31+0900
Task
C - 魔法の訓練 (Magical Training)
User
fura2
Language
IOI-Style C++ (GCC 5.4.1)
Score
100
Code Size
4594 Byte
Status
AC
Exec Time
2437 ms
Memory
22612 KB
Compile Error
./grader.cpp: In function ‘int main()’:
./grader.cpp:11: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result
./grader.cpp:13: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result
./grader.cpp:14: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result
./grader.cpp:18: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result
Judge Result
Set Name
Subtask1
Subtask2
Subtask3
Subtask4
Score / Max Score
12 / 12
18 / 18
30 / 30
40 / 40
Status
Set Name
Test Cases
Subtask1
subtask1/1, subtask1/10, subtask1/2, subtask1/3, subtask1/4, subtask1/5, subtask1/6, subtask1/7, subtask1/8, subtask1/9
Subtask2
subtask2/1, subtask2/2, subtask2/3, subtask2/4, subtask2/5, subtask2/6, subtask2/7, subtask2/8, subtask2/9
Subtask3
subtask3/1, subtask3/2, subtask3/3, subtask3/4, subtask3/5, subtask3/6, subtask3/7
Subtask4
subtask4/1, subtask4/10, subtask4/11, subtask4/12, subtask4/2, subtask4/3, subtask4/4, subtask4/5, subtask4/6, subtask4/7, subtask4/8, subtask4/9
Case Name
Status
Exec Time
Memory
subtask1/1
AC
24 ms
1004 KB
subtask1/10
AC
27 ms
1000 KB
subtask1/2
AC
24 ms
940 KB
subtask1/3
AC
25 ms
1004 KB
subtask1/4
AC
25 ms
996 KB
subtask1/5
AC
26 ms
1000 KB
subtask1/6
AC
23 ms
992 KB
subtask1/7
AC
23 ms
992 KB
subtask1/8
AC
24 ms
1000 KB
subtask1/9
AC
25 ms
1000 KB
subtask2/1
AC
120 ms
1456 KB
subtask2/2
AC
199 ms
2096 KB
subtask2/3
AC
255 ms
3048 KB
subtask2/4
AC
268 ms
3000 KB
subtask2/5
AC
261 ms
3000 KB
subtask2/6
AC
250 ms
2996 KB
subtask2/7
AC
263 ms
2988 KB
subtask2/8
AC
193 ms
2944 KB
subtask2/9
AC
255 ms
2984 KB
subtask3/1
AC
747 ms
5984 KB
subtask3/2
AC
1376 ms
13612 KB
subtask3/3
AC
1682 ms
22492 KB
subtask3/4
AC
1651 ms
22368 KB
subtask3/5
AC
1375 ms
22428 KB
subtask3/6
AC
1608 ms
22432 KB
subtask3/7
AC
2063 ms
22444 KB
subtask4/1
AC
2437 ms
22252 KB
subtask4/10
AC
1632 ms
22316 KB
subtask4/11
AC
1946 ms
22420 KB
subtask4/12
AC
2391 ms
22232 KB
subtask4/2
AC
2283 ms
22448 KB
subtask4/3
AC
2180 ms
22428 KB
subtask4/4
AC
2063 ms
22364 KB
subtask4/5
AC
1685 ms
22612 KB
subtask4/6
AC
1517 ms
22284 KB
subtask4/7
AC
1899 ms
22560 KB
subtask4/8
AC
2121 ms
22376 KB
subtask4/9
AC
2384 ms
22224 KB