問題描述
mr_h 出了一道資訊學競賽題,就是給 n 個數排序。輸入格式是這樣的:
試題有若干組資料。每組資料的第乙個是乙個整數 n,表示總共有 n 個數待排序;接下來 n 個整數,分別表示這n 個待排序的數。
例如:3 4 2 –1 4 1 2 3 4,就表示有兩組資料。第一組有3 個數(4,2,-1),第二組有4個數(1,2,3,4)。可是現在mr_h 做的輸入資料出了一些問題。
例如:2 1 9 3 2 按理說第一組資料有2 個數(1,9),第二組資料有3 個數,可是「3」後面並沒有出現三個數,只出現了乙個數「2」而已!
現在 mr_h 需要對資料進行修改,改動中「一步」的含義是對檔案中的某乙個數+1 或-1,寫個
程式,計算最少需要多少步才能將資料改得合法。
輸入格式
第一行乙個整數m,表示mr_h 做的輸入資料報含的整數個數。第二行包含m 個整數a[i],每個整數的絕對值不超過10000。
輸出格式
乙個整數,表示把資料修改為合法的情況下,最少需要多少步。
樣例輸入
【樣例輸入1】
41 9 3 2
【樣例輸入2】
104 4 3 5 0 -4 -2 -1 3 5
樣例輸出
【樣例輸出1】
2【樣例輸出2】
3
提示【資料範圍】
對於 20%的資料,m<=10, |a[i]|<=5;
對於60%的資料,m<=5000, |a[i]|<=10000
對於100%的資料,m<=100000, |a[i]|<=10000
** by yz
【題解】
dp(i)=min
num(j+1)-(i-j-1)>=0 ,即inum(j+1)+j+1時 dp(i)=min-i
我們不難用一顆權值線段樹去維護,線段樹的下標表示num(j+1)+j+1
,值為dp(j)-num(j+1)-j-1
/ dp(j)+num(j+1)+j+1
的最小值。
查詢dp(j)+num(j+1)+j+1線段樹的i....max和
dp(j)-num(j+1)-j-1
線段樹的1...i-1即可
對拍無誤
1 #include 2 #include 3 #include 4 #include 5my#define max(a, b) ((a) > (b) ? (a) : (b))
6#define min(a, b) ((a) < (b) ? (a) : (b))
78 inline void read(int &x)915
16const
int maxm = 200000 + 10;17
const
int maxnum = 1000000;18
const
int pian = 11000;19
const
int inf = 0x3f3f3f3f;20
21int
m,dp[maxm],num[maxm];
2223
int mi[2][maxnum + 10
], sum;
24/*
25f(i)=min
260: num(j+1)-(i-j-1)>0 -> i27
1: num(j+1)-(i-j-1)<=0 -> i>num(j+1)+j+1 f(i)=min + i
28*/
2930
void modify(int a, int p, int k, int o = 1, int l = 1, int r = sum +pian)
3137
int mid = (l + r) >> 1;38
if(mid >= p)modify(a, p, k, o << 1
, l, mid);
39else modify(a, p, k, o << 1 | 1, mid + 1
, r);
40 mi[a][o] = min(mi[a][o], min(mi[a][o << 1], mi[a][o << 1 | 1
]));41}
4243
int ask(int a, int ll, int rr, int o = 1, int l = 1, int r = sum +pian)
4452
53int
main()
5472 printf("%d"
, dp[m]);
73return0;
74 }
1 #include2 #include3 #include4 #include5 #include6 #include7stdusing
namespace
std;
8const
int inf=0x3f3f3f3f
;9 template 10 inline void _read(t&x)
14for(x=0;t>='
0'&&t<='
9';t=getchar())x=x*10+t-'0'
;15if(!sign)x=-x;16}
17int
n;18
int a[200005
];19
int f[200005
];20
int mark[200005
];21 vector v[200005
];22
struct
node
25 node(int g,int h)
26bool
operator
< (const node p)const
29};
30 priority_queueq1;
31 priority_queueq2;
32void
dajia()39}
40}41void
daqunjia()
50while(q1.size()&&mark[q1.top().x]==2)53
if(q1.size())
56if
(q2.size())
60 f[i]=temp;
61if(mark[i]==2)64
else q1.push(node(i,f[i]+a[i+1]+i+1
));65
} 66}67
intmain()
76if(n<=5000
)dajia();
77else
daqunjia();
78 cout<
79 }
1 #include 2rand3const
int maxn = 100000;4
const
int maxnum = 10000;5
6int
main()717
return0;
18 }
多校4 櫥櫃
include include include include includeusing namespace std int s1 400100 int s2 400100 struct node struct cmp int main int i,j,m,n while scanf d d n,m...
多校聯賽總結
首先是一些資料 2014 multi university training contest 1 by fzu a 數學 費馬小定理 b 網路流 最小k路徑覆蓋 c 樹形dp 樹的重心 資料結構 d 貪心 巧妙 e 數學 dp 隱含馬爾科夫模型 f 線段樹 函式式 二分 g 線段樹 狀態壓縮 h 模...
多校聯賽 Envy
我們讓 n 個人站成一排,編號為 1 n,每個人都有乙個數字代表他這次比賽的成績,對於每個人,如果他後面 編號大於他的人中 存在乙個人的成績大於等於他,那麼他的嫉妒值為他們之間的距離。兩個點 a和 b 之間的距離為 abs a b 例如 4,3,6,2 那麼第 1 個人對第 3 個人有 2 點嫉妒值...