NOIP2002-2017提高组题解
给个人认为比较难的题目打上'*'
NOIP2002(clear)
//一个很吼的贪心题,将平均数减掉之后从左往右将影响消除
#include<bits/stdc++.h>
using namespace std;
];
int main()
{
, sum = ;
cin >> n;
; i < n ; i++)
{
cin >> num[i];
sum += num[i];
}
sum /= n;
; i < n ; i++)
{
num[i] -= sum;
if(num[i])
{
cou++;
num[i + ] += num[i];
}
}
cout << cou;
;
}
均分纸牌
//bfs,注意一个串可能可以变换成多个串
#include<bits/stdc++.h>
using namespace std;
struct p{
string n;
int s;
}ans;
set < string > uni;
multimap < string , string > dis;
queue < p > q;
int main()
{
string tar , a , b;
cin >> ans.n >> tar;
q.push(ans);
uni.insert(ans.n);
while(cin >> a >> b) dis.insert(pair<string , string>(a , b));
while(!q.empty())
{
ans = q.front();
q.pop();
) break;
if(ans.n == tar)
{
cout << ans.s;
;
}
ans.s++;
; i < ans.n.size() ; i++)
; j <= i ; j++)
)))
for(multimap<string , string>::iterator iter = dis.begin() ; iter != dis.end() ; iter++)
))
{
, j) + iter -> second + , (int)ans.n.length() - i);
if(!uni.count(newS))
{
uni.insert(newS);
p t;
t.n = newS;
t.s = ans.s;
q.push(t);
}
}
}
cout << "NO ANSWER!";
;
}
字串变换
//题目叙述似乎不是很清楚,看懂了直接上公式就行
#include<bits/stdc++.h>
#define eps 1e-4
//This code is written by Itst
using namespace std;
int main(){
#ifdef LG
freopen("1033.in" , "r" , stdin);
//freopen("1033.out" , "w" , stdout);
#endif
long double H , S , V , L , K , N;
cin >> H >> S >> V >> L >> K >> N;
long double rangeR = eps + S + L - V * sqrt((H - K) * 0.2) , rangeL = S - eps - V * sqrt(H * 0.2);
;
; i < N ; i++)
if(i >= rangeL && i <= rangeR)
cnt++;
cout << cnt;
;
}
自由落体
//爆搜+覆盖剪枝+最优化剪枝
#include<bits/stdc++.h>
//This code is written by Itst
using namespace std;
inline int read(){
;
;
char c = getchar();
while(c != EOF && !isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(c != EOF && isdigit(c)){
a = (a << ) + (a << ) + (c ^ ');
c = getchar();
}
return f ? -a : a;
}
][] , tria[][] , N , K , ans = 0x7fffffff;
bool check(int i , int j){
] < tria[j][] || tria[j][] < tria[i][] || tria[i][] < tria[j][] || tria[i][] > tria[j][];
}
void dfs(int now , int sum){
if(sum > ans)
return;
if(now > N){
ans = sum;
return;
}
][] , newSum = sum;
memcpy(temp , tria , sizeof(tria));
; i <= K ; i++){
] < tria[i][])
newSum -= (tria[i][] - tria[i][]) * (tria[i][] - tria[i][]);
tria[i][] = min(tria[i][] , node[now][]);
tria[i][] = max(tria[i][] , node[now][]);
tria[i][] = min(tria[i][] , node[now][]);
tria[i][] = max(tria[i][] , node[now][]);
newSum += (tria[i][] - tria[i][]) * (tria[i][] - tria[i][]);
;
; f && j <= K ; j++)
if(j != i)
f = check(i , j);
if(f)
dfs(now + , newSum);
memcpy(tria , temp , sizeof(tria));
newSum = sum;
}
}
int main(){
#ifdef OJ
freopen("1034.in" , "r" , stdin);
//freopen("1034.out" , "w" , stdout);
#endif
N = read();
K = read();
; i <= N ; i++){
node[i][] = read();
node[i][] = read();
}
; i <= K ; i++){
tria[i][] = tria[i][] = ;
tria[i][] = tria[i][] = ;
}
dfs( , );
cout << ans;
;
}
*矩形覆盖
NOIP2003(clear)
//拓扑排序模板题
#include<bits/stdc++.h>
using namespace std;
inline int read(){
;
;
char c = getchar();
while(!isdigit(c)){
;
c = getchar();
}
) + (a << ) + (c ^ ') , c = getchar();
return k ? -a : a;
}
vector < ] , W[];
] , U[] , num[];
int main(){
int N = read() , P = read();
queue < int > q;
priority_queue < int , vector < int > , greater < int > > q1;
; i <= N ; i++){
if(C[i] = read()){
q.push(i);
read();
}
else C[i] -= read();
}
while(P--){
int a = read() , b = read();
Ed[a].push_back(b);
W[a].push_back(read());
num[b]++;
}
while(!q.empty()){
int t = q.front();
q.pop();
if(Ed[t].size())
; i ^ Ed[t].size() ; i++){
) C[Ed[t][i]] += W[t][i] * C[t];
if(!--num[Ed[t][i]]) q.push(Ed[t][i]);
}
) q1.push(t);
}
if(q1.empty()) cout << "NULL";
while(!q1.empty()){
cout << q1.top() << ' ' << C[q1.top()] << endl;
q1.pop();
}
;
}
神经网络
//区间DP,设f[i][j]表示i到j的点组成的二叉树中得分最高的方式,合并枚举根即可
#include<bits/stdc++.h>
using namespace std;
] , p[][];
][];
void dfs(int f , int l)
{
if(f >= l)
{
if(f == l) cout << f << " ";
return;
}
cout << p[f][l] << " ";
dfs(f , p[f][l] - );
dfs(p[f][l] + , l);
}
int main(){
ios::sync_with_stdio(false);
cin >> n;
; i <= n ; i++) vis[][i] = ;
; i <= n ; i++)
{
; j <= n ; j++) vis[i][j] = ;
cin >> num[i];
vis[i][i] = num[i];
}
; i <= n ; i++) vis[n + ][i] = ;
; i <= n - ; i++)
; j + i <= n ; j++)
for(int k = j ; k <= j + i ; k++)
] * vis[k + ][j + i] + num[k] > vis[j][i + j])
{
vis[j][i + j] = vis[j][k - ] * vis[k + ][j + i] + num[k];
p[j][j + i] = k;
}
cout << vis[][n] << endl;
dfs( , n);
;
}
加分二叉树
//暴搜,根据贪心不难知道每一次切断的一定是当前被感染的点和其没被感染的儿子之间的边
#include<bits/stdc++.h>
using namespace std;
inline int read(){
;
char c = getchar();
while(!isdigit(c)) c = getchar();
) + (a << ) + (c ^ ) , c = getchar();
return a;
}
inline int min(int a , int b){
return a < b ? a : b;
}
vector < ];
queue < int > q;
int minN = 0x3f3f3f3f;
];
void choose(int , queue < int >);
void create(int num , queue < int > q){
queue < int > q1;
register ;
while(!q.empty()){
int t = q.front();
q.pop();
num++;
; i < Ed[t].size() ; i++)
if(!vis[Ed[t][i]]){
q1.push(Ed[t][i]);
if(num + ++sum > minN) return;
}
}
if(num + sum > minN) return;
){
minN = min(minN , num);
return;
}
choose(num , q1);
}
int main(){
register int n = read() , p = read();
; i - p ; i++){
int a = read() , b = read();
Ed[a].push_back(b);
Ed[b].push_back(a);
}
q.push();
vis[] = ;
create( , q);
printf("%d" , minN);
;
}
void choose(int num , queue < int > q){
register int first = q.front();
do{
vis[q.front()] = ;
q.push(q.front());
q.pop();
}while(q.front() - first);
do{
register int t = q.front();
q.pop();
create(num , q);
q.push(t);
}while(q.front() - first);
while(!q.empty()){
vis[q.front()] = ;
q.pop();
}
}
传染病控制
//为什么会有这么玄学的题目???
//注意:①I可能为人名;②在某种状态没有人被认为时Guilty的时候,考虑被指正不是Guilty的人;③有可能多种情况同一结果
#include<bits/stdc++.h>
//This code is written by Itst
using namespace std;
inline int read(){
;
;
char c = getchar();
while(c != EOF && !isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(c != EOF && isdigit(c)){
a = (a << ) + (a << ) + (c ^ ');
c = getchar();
}
return f ? -a : a;
}
map < string , int > day , name;
][] , notG[][] , date[][] , mark[] , nowG[] , nowNotG[] , nowDate[] , nowNotDate[];
int N , M , P;
];
void check(){
memset(nowG , , sizeof(nowG));
memset(nowNotG , , sizeof(nowNotG));
memset(nowDate , , sizeof(nowDate));
memset(nowNotDate , , sizeof(nowNotDate));
; i <= M ; i++)
if(!mark[i]){
; j <= M ; j++)
if(G[i][j])
nowG[j] = ;
; j <= M ; j++)
if(notG[i][j])
nowNotG[j] = ;
; j <= ; j++)
if(date[i][j])
nowDate[j] = ;
}
else{
; j <= M ; j++)
if(G[i][j])
nowNotG[j] = ;
; j <= M ; j++)
if(notG[i][j])
nowG[j] = ;
; j <= ; j++)
if(date[i][j])
nowNotDate[j] = ;
}
, ifGuilty = ;
; i <= M ; i++)
if(nowG[i])
if(ifGuilty || nowNotG[i])
return;
else
ifGuilty = ;
; i <= ; i++)
if(nowDate[i])
if(ifDate || nowNotDate[i])
return;
else
ifDate = ;
if(!ifGuilty)
; i <= M ; i++)
if(!nowNotG[i])
if(!ifGuilty)
ifGuilty = ;
else{
puts("Cannot Determine");
exit();
}
if(ifGuilty){
; i <= M ; i++)
if(nowG[i]){
if(!answer.empty() && answer != ori[i]){
puts("Cannot Determine");
exit();
}
answer = ori[i];
return;
}
; i <= M ; i++)
if(!nowNotG[i]){
if(!answer.empty() && answer != ori[i]){
puts("Cannot Determine");
exit();
}
answer = ori[i];
return;
}
}
else{
puts("Cannot Determine");
exit();
}
}
void dfs(int now , int cnt){
if(now > M){
if(cnt == N)
check();
return;
}
dfs(now + , cnt);
mark[now] = ;
dfs(now + , cnt + );
mark[now] = ;
}
int main(){
#ifdef OJ
freopen("1039.in" , "r" , stdin);
//freopen("1039.out" , "w" , stdout);
#endif
day[;
day[;
day[;
day[;
day[;
day[;
day[;
M = read();
N = read();
P = read();
string s , now;
; i <= M ; i++){
cin >> ori[i];
name[ori[i]] = i;
}
getline(cin , s);
stringstream ss;
; i <= P ; i++){
getline(cin , s);
if(!s.empty() && *--s.end() == '\r')
s.erase(--s.end());
ss.clear();
ss.str(s);
ss >> s;
s.erase(--s.end());
int t = name[s];
if(!t)
continue;
while(ss >> s)
if(s == "I"){
ss >> now;
if(now != "am"){
if(now != "is" || !name.count("I"))
break;
int k = name["I"];
ss >> now;
if(now != "guilty." && now != "not")
break;
if(now == "guilty.")
G[t][k] = ;
else{
ss >> now;
if(now == "guilty.")
notG[t][k] = ;
}
continue;
}
ss >> now;
if(now != "guilty." && now != "not")
break;
if(now == "guilty.")
G[t][t] = ;
else{
ss >> now;
if(now == "guilty.")
notG[t][t] = ;
}
}
else
if(name.count(s)){
int k = name[s];
ss >> now;
if(now != "is")
break;
ss >> now;
if(now != "guilty." && now != "not")
break;
if(now == "guilty.")
G[t][k] = ;
else{
ss >> now;
if(now == "guilty.")
notG[t][k] = ;
}
}
else
if(s == "Today"){
ss >> now;
if(now != "is")
break;
ss >> now;
if(now.empty())
break;
now.erase(--now.end());
if(!day.count(now))
break;
date[t][day[now]] = ;
}
else
break;
}
dfs( , );
if(answer.empty())
puts("Impossible");
else
cout << answer;
;
}
*侦探推理
NOIP2004(clear)
//...
#include<bits/stdc++.h>
using namespace std;
int main()
{
, c = ;
; i <= ; i++)
{
int a;
cin >> a;
if(mon < a)
{
cout << "-" << i;
;
}
c += (mon - a) / * ;
mon = (mon - a) % + ;
}
cout << c / * + mon - ;
;
}
津津的储蓄计划
//每一次贪心地合并两个重量最少的果子
#include<bits/stdc++.h>
using namespace std;
queue <int> p , q;
];
int main(){
;
cin >> n;
; i < n ; i++) cin >> a[i];
sort(a , a + n);
; i < n ; i++) p.push(a[i]);
; !p.empty() || q.size() != ; i++)
{
int a , b;
if(p.empty())
{
a = q.front();
q.pop();
}
else
if(q.empty())
{
a = p.front();
p.pop();
}
else
{
int x = p.front() , y = q.front();
if(x <= y)
{
a = x;
p.pop();
}
else
{
a = y;
q.pop();
}
}
if(p.empty())
{
b = q.front();
q.pop();
}
else
if(q.empty())
{
b = p.front();
p.pop();
}
else
{
int x = p.front() , y = q.front();
if(x <= y)
{
b = x;
p.pop();
}
else
{
b = y;
q.pop();
}
}
sum += a + b;
q.push(a + b);
}
cout << sum;
;
}
合并果子
//DP,从左往右、从右往左做两边LIS算最大权值
#include<bits/stdc++.h>
using namespace std;
] , b[] , c[];
int main()
{
std::ios::sync_with_stdio(false);
;
cin >> n;
; i < n ; i++)
{
cin >> num[i];
; j + ; j--)
if(num[i] > num[j] && b[i] < b[j])
b[i] = b[j];
b[i]++;
}
; i + ; i--)
{
; j - n ; j++)
if(num[i] > num[j] && c[i] < c[j])
c[i] = c[j];
c[i]++;
maxN = max(maxN , b[i] + c[i] - );
}
cout << n - maxN;
;
}
合唱队形
//搜索要注意剪枝(看前边是否有不论进位与否都不满足条件的竖式),也可以高斯消元
#include<bits/stdc++.h>
using namespace std;
][];
] , N , num[] , vis[];
void dfs(int a , int i)
{
)
{
; i < N ; i++)
printf("%d " , num[i]);
exit();
}
; k < a ; k++)
][k] - && num[s[][k] - && num[s[][k] - && (num[s[][k] - ][k] - ][k] - ][k] - ][k] - - num[s[][k] - 'A']) % N)
return;
][a] - && num[s[][a] - && num[s[][a] - )
{
][a] - ][a] - ][a] - 'A'])
{
jw[a - ] = (num[s[][a] - ][a] - 'A'] + jw[a]) / N;
]);
dfs(a - , );
}
}
else
)
{
][a] - ][a] - 'A'] + jw[a];
][a] - 'A'] != n % N)
return;
jw[a - ] = n / N;
][a] - )
{
num[s[][a] - 'A'] = n % N;
vis[n % N] = ;
dfs(a - , );
vis[n % N] = ;
num[s[][a] - ;
}
else
dfs(a - , );
}
else
))
{
; j >= ; j--)
if(!vis[j])
{
vis[j] = ;
num[s[i][a] - 'A'] = j;
dfs(a , i + );
num[s[i][a] - ;
vis[j] = ;
}
}
else
dfs(a , i + );
}
int main()
{
scanf(] , s[] , s[]);
memset(num , - , sizeof(num));
dfs(N - , );
;
}
*虫食算
NOIP2005(clear)
//条件判断练习题
#include<bits/stdc++.h>
#define I ans[i].
using namespace std;
struct scho{
string name;
char gb , xb;
int numL , aveSco , claSco , scho;
inline void input()
{
cin >> name >> aveSco >> claSco >> gb >> xb >> numL;
&& numL) scho += ;
&& claSco > ) scho += ;
) scho += ;
) scho += ;
) scho += ;
}
}ans[];
int main()
{
ios::sync_with_stdio(false);
, maxScho = - , maxD = ;
cin >> n;
; i < n ; i++)
{
ans[i].input();
sumScho += ans[i].scho;
if(maxScho < ans[i].scho)
{
maxScho = ans[i].scho;
maxD = i;
}
}
cout << ans[maxD].name << endl << maxScho << endl << sumScho;
;
}
谁拿了最多奖学金
//DP并压缩路径,根据NOIP2017D1T1结论可以知道当路径长度>=72的时候可以直接压成72,因为72以及之后的都一定可以被到达
//然而代码里面压的是2520
#include<bits/stdc++.h>
using namespace std;
] , c[] , minN[];
];
inline int min(int a , int b){
return a < b ? a : b;
}
int main(){
int L , S , T , M;
scanf("%d%d%d%d" , &L , &S , &T , &M);
; i < M ; i++) scanf("%d" , a + i);
sort(a , a + M);
a[M] = L;
c[] = a[] % ;
; i <= M ; i++){
] , b = tmp % ;
&& b <= T) b += ;
c[i] = c[i - ] + b;
}
; i < M ; i++) f[c[i]] = ;
memset(minN , 0x3f , sizeof(minN));
minN[] = ;
; i < c[M] ; i++){
for(int j = S; j <= T && j <= i ; j++)
minN[i] = min(minN[i] , minN[i - j]);
minN[i] += f[i];
}
int Min = 0x3f3f3f3f;
for(int i = c[M] - T ; i - c[M] ; i++)
Min = min(Min , minN[i]);
cout << Min;
;
}
*过河
//正着、反着把环断成链,考虑最多有多少个人可以不移动
#include<bits/stdc++.h>
//This code is written by Itst
using namespace std;
inline int read(){
;
;
char c = getchar();
while(c != EOF && !isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(c != EOF && isdigit(c)){
a = (a << ) + (a << ) + (c ^ ');
c = getchar();
}
return f ? -a : a;
}
;
];
bool vis[MAXN];
int main(){
#ifdef OJ
freopen("1053.in" , "r" , stdin);
//freopen("1053.out" , "w" , stdout);
#endif
, cnt = ;
; i <= N ; i++){
l[i] = read();
r[i] = read();
}
pre = l[];
vis[] = ;
pot[] = ;
; i <= N ; i++){
if(l[dir] == pre){
pre = dir;
dir = r[dir];
}
else{
pre = dir;
dir = l[dir];
}
if(vis[dir]){
puts("-1");
;
}
vis[dir] = ;
pot[(i - dir + N) % N]++;
}
; i < N ; i++)
cnt = max(cnt , pot[i]);
memset(pot , , sizeof(pot));
pre = r[];
dir = ;
pot[] = ;
; i <= N ; i++){
if(l[dir] == pre){
pre = dir;
dir = r[dir];
}
else{
pre = dir;
dir = l[dir];
}
pot[(i - dir + N) % N]++;
}
; i < N ; i++)
cnt = max(cnt , pot[i]);
printf("%d\n" , N - cnt);
;
}
篝火晚会
//找到值带入a即可
#include<bits/stdc++.h>
#define int long long
//This code is written by Itst
using namespace std;
inline int read(){
;
;
char c = getchar();
while(c != EOF && !isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(c != EOF && isdigit(c)){
a = (a << ) + (a << ) + (c ^ ');
c = getchar();
}
return f ? -a : a;
}
;
][] = { , , , , , , , , , , , };
] = "()^*+-";
];
];
] , pos[];
map < char , int > ctoi;
int calc(int a , int b , int pos){
;
switch(pos){
:
while(b){
)
ans = ans * a % MOD;
a = a * a % MOD;
b >>= ;
}
break;
:
ans = a * b % MOD;
break;
:
ans = (a + b) % MOD;
break;
:
ans = (a - b + MOD) % MOD;
break;
}
return ans;
}
int calc(string s , int a){
, topPos = , nowNum = ;
;
pos[] = ;
s = s + ")";
; i < s.size() ; i++)
if(s[i] == ' ' || s[i] == '\r' || s[i] == '\n')
continue;
else
if(isdigit(s[i])){
nowNum = nowNum * + s[i] - ';
f = ;
}
else
if(s[i] == 'a')
num[++topNum] = a;
else{
if(f){
num[++topNum] = nowNum;
nowNum = f = ;
}
int t = ctoi[s[i]];
] > yxj[t][]){
num[topNum - ] = calc(num[topNum - ] , num[topNum] , pos[topPos]);
topNum--;
topPos--;
}
] == yxj[t][])
topPos--;
else
pos[++topPos] = t;
}
];
}
inline void getString(string& s){
char c = getchar();
while(c == '\r' || c == '\n')
c = getchar();
while(!(c == '\r' || c == '\n' || c == EOF)){
s = s + c;
c = getchar();
}
}
signed main(){
#ifdef OJ
freopen("1054.in" , "r" , stdin);
//freopen("1054.out" , "w" , stdout);
#endif
; i < ; i++)
ctoi[to[i]] = i;
getString(mod);
int N = read();
; i <= N ; i++)
getString(now[i]);
; i <= ; i++){
int t = calc(mod , i);
; j <= N ; j++)
if(calc(now[j] , i) != t)
vis[j] = ;
}
; i <= N ; i++)
if(!vis[i])
putchar(i + );
;
}
等价表达式
NOIP2006(clear)
//区间DP、断环成链
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll fast_read()
{
char c = getchar();
ll a = ;
;
while(!isdigit(c))
{
;
c = getchar();
}
) + (a << ) + c - ' , c = getchar();
return k ? -a : a;
}
inline void fast_print(ll x)
{
] , dirN = -;
) putchar('-') , x = -x;
, x /= ;
) putchar(');
) putchar(num[dirN--] + );
putchar('\n');
}
] , maxN[][];
int main()
{
;
; i < m ; i++) num[i] = fast_read();
; i <= m ; i++)
; j < m ; j++)
; k < i + j ; k++)
maxN[j][(i + j) % m] = max(maxN[j][(i + j) % m] ,
maxN[j][k % m] + maxN[k % m][(i + j) % m] + num[j] * num[k % m] * num[(j + i) % m]);
; i < m ; i++) maxAll = max(maxAll , maxN[i][i]);
fast_print(maxAll);
;
}
能量项链
//依赖背包弱化版,直接枚举一棵依赖关系树里面的选择即可
#include<bits/stdc++.h>
using namespace std;
struct ys{
] , wei[] , index;
}ans[];
] , visa[];
int main()
{
;
cin >> N >> M;
N /= ;
; i <= M ; i++)
{
int a , b , c;
cin >> a >> b >> c;
a /= ;
if(c)
{
; i < dirA ; i++)
if(ans[i].index == c)
{
)
{
ans[i].wei[] = ans[i].wei[] + a;
ans[i].mon[] = ans[i].mon[] + a * b;
}
else
{
ans[i].wei[] = ans[i].wei[] + a;
ans[i].wei[] = ans[i].wei[] + a;
ans[i].mon[] = ans[i].mon[] + a * b;
ans[i].mon[] = ans[i].mon[] + a * b;
}
ans[i].dirN++;
}
}
else{
ans[dirA].dirN = ;
ans[dirA].mon[] = a * b;
ans[dirA].wei[] = a;
ans[dirA++].index = i;
}
}
; i < dirA ; i++)
{
; j <= N ; j++) visa[j] = vis[j];
; j < && ans[i].mon[j] ; j++)
; k--)
visa[k + ans[i].wei[j]] = max(visa[k + ans[i].wei[j]] , vis[k] + ans[i].mon[j]);
; j <= N ; j++) vis[j] = visa[j];
}
cout << vis[N] * ;
;
}
金明的预算方案
//递推,设f[i][j]表示从后往前第i位,数字为j时候的方案数,记得写高精
#include<bits/stdc++.h>
using namespace std;
struct BigNum{
];
BigNum(){
memset(num , , sizeof(num));
}
void operator =(int k){
while(k){
num[++num[]] = k % ;
k /= ;
}
}
BigNum operator +(BigNum a){
BigNum c;
c.num[] = num[] > a.num[] ? num[] : a.num[];
; i <= c.num[] ; i++)
){
++c.num[i + ];
c.num[i] -= ;
}
] + ])
++c.num[];
return c;
}
inline void output(){
])
putchar(');
] ; i ; i--)
putchar(num[i] + );
}
};
, , , , , , , , , };
BigNum sum , *ans[];
int main()
{
int K , W;
cin >> K >> W;
; i <= W / K + ; i++)
ans[i] = new BigNum[pow2[K]];
; i < pow2[K] ; i++)
ans[][i] = ;
; (j - ) * K < W ; j++)
; k ; k--){
ans[j][k] = ans[j][k + ] + ans[j - ][k + ];
) * K < W)
sum = sum + ans[j][k];
}
sum.output();
;
}
2^k进制数
//模拟题
#include<bits/stdc++.h>
//This code is written by Itst
using namespace std;
inline int read(){
;
;
char c = getchar();
while(c != EOF && !isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(c != EOF && isdigit(c)){
a = (a << ) + (a << ) + (c ^ ');
c = getchar();
}
return f ? -a : a;
}
] , to[][] , times[][] , need[] , spend[];
][];
int main(){
#ifdef OJ
freopen("1065.in" , "r" , stdin);
//freopen("1065.out" , "w" , stdout);
#endif
M = read();
N = read();
;
; i <= N * M ; i++)
need[i] = read();
; i <= N ; i++)
; j <= M ; j++)
to[i][j] = read();
; i <= N ; i++)
; j <= M ; j++)
times[i][j] = read();
; i <= N * M ; i++){
in[need[i]]++;
; j++){
;
; f && k < times[need[i]][in[need[i]]] ; k++)
if(vis[to[need[i]][in[need[i]]]][j + k]){
f = ;
j = j + k;
}
if(f){
; k < times[need[i]][in[need[i]]] ; k++)
vis[to[need[i]][;
maxN = max(maxN , j + times[need[i]][in[need[i]]]);
spend[need[i]] = j + times[need[i]][in[need[i]]];
break;
}
}
}
cout << maxN;
;
}
作业调度方案
NOIP2007(clear)
//又要写高精...每一行是独立的,考虑区间DP,(倒序DP方式:)设f[i][j]表示最后选择i到j的最大得分,每一次枚举左右即可。
#include<bits/stdc++.h>
using namespace std;
struct BN{
];
int& operator [](int x){return num[x];}
BN& operator =(const char *c){
, k = ;
; i <= n ; i++){
) j++ , k = ;
num[j] += k * (c[n - i] ^ );
k = (k << ) + (k << );
}
num[] = j;
return *this;
}
BN(){memset(num , , sizeof(num));}
BN(const BN &a){memcpy(num , a.num , sizeof(num));}
BN( , sizeof(num));*this = s;}
BN operator +(BN a){
BN c;
c[] = max(a[] , num[]);
; i <= c[] ; i++)
){
c[i + ]++;
c[i] -= ;
}
] + ]) ++c[];
return c;
}
BN operator *(int a){
BN c;
c[] = num[];
; i <= num[] ; i++)
c[i] = num[i] << ;
; i <= c[] ; i++)
){
c[i + ] += c[i] / ;
c[i] %= ;
}
] + ]) c[]++;
return c;
}
}maxN[][];
inline BN input(){
] = {};
scanf("%s" , c);
return BN(c);
}
inline void output(BN n){
printf(]]);
]) printf(]]);
}
inline BN max(BN a , BN b){
] > b[]) return a;
] < b[]) return b;
] ; i ; i--)
if(a[i] > b[i]) return a;
else if(a[i] < b[i]) return b;
return a;
}
int main(){
BN sum;
int N , M;
for(scanf("%d%d" , &N , &M) ; N ; N--){
; i <= M ; i++) maxN[i][i] = input();
; i ^ M ; i++)
; j + i <= M ; j++)
maxN[j][j + i] = max(maxN[j][j] + maxN[j + ][j + i] * , maxN[j + i][j + i] + maxN[j][j + i - ] * );
sum = sum + maxN[][M] * ;
}
output(sum);
;
}
矩阵取数游戏
//随你怎么写,不用桶排序就行
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll fast_read()
{
char c = getchar();
ll a = ;
;
while(!isdigit(c))
{
;
c = getchar();
}
) + (a << ) + c - ' , c = getchar();
return k ? -a : a;
}
inline void fast_print(ll x)
{
] , dirN = -;
) putchar('-') , x = -x;
, x /= ;
) putchar(');
) putchar(num[dirN--] + );
}
map < int , int > m;
int main()
{
for(int n = fast_read() ; n ; n--)
m[fast_read()]++;
for(map < int , int >::iterator i = m.begin() ; i != m.end() ; i++)
{
fast_print(i -> first);
putchar(' ');
fast_print(i -> second);
putchar('\n');
}
;
}
统计数字
//模拟题,务必注意细节
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
int p1 , p2 , p3;
string s;
cin >> p1 >> p2 >> p3 >> s;
; i < s.size() ; i++)
if(s[i] - '-') cout << s[i];
else{
] >= s[i + ] || !((s[i - ] >= ] >= ] >= ] >= ] <= ] <= ')))
cout << s[i];
else
{
string st;
] + ; k < s[i + ] ; k++)
; j < p2 ; j++) st += k;
) reverse(st.begin() , st.end());
switch(p1)
{
:
cout << st;
break;
:
{
; i < st.size() ; i++)
if(st[i] >= 'a') st[i] -= 'a' - 'A';
cout << st;
break;
}
default:
cout << string(st.size() , '*');
}
}
}
;
}
字符串的展开
//进阶指南上面讲得很好啊qwq要在这里说要说很多所以就自行领悟吧qwq话说这道题的直径有很好的性质
#include<bits/stdc++.h>
#define LG
//This code is written by Itst
using namespace std;
inline int read(){
;
;
char c = getchar();
while(c != EOF && !isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(c != EOF && isdigit(c)){
a = (a << ) + (a << ) + (c ^ ');
c = getchar();
}
return f ? -a : a;
}
;
struct Edge{
int end , upEd , w;
}Ed[MAXN << ];
] , head[MAXN] , N , cntEd = , maxLen , maxDir , cntRoute , sum;
inline void addEd(int a , int b , int c){
Ed[++cntEd].end = b;
Ed[cntEd].upEd = head[a];
Ed[cntEd].w = c;
head[a] = cntEd;
}
void dfs(int now , int fa , int len){
for(int i = head[now] ; i ; i = Ed[i].upEd)
if(Ed[i].end != fa){
pre[Ed[i].end] = i;
dfs(Ed[i].end , now , len + Ed[i].w);
}
if(maxLen < len){
maxLen = len;
maxDir = now;
}
}
void getRoute(int start , int end){
while(end != start){
route[++cntRoute][] = end;
route[cntRoute][] = Ed[pre[end]].w;
sum += Ed[pre[end]].w;
end = Ed[pre[end] ^ ].end;
}
route[++cntRoute][] = start;
}
void Dfs(int now , int belong , int fa , int len){
for(int i = head[now] ; i ; i = Ed[i].upEd)
][] && Ed[i].end != route[belong + ][])
Dfs(Ed[i].end , belong , now , len + Ed[i].w);
maxL[belong] = max(maxL[belong] , len);
}
int main(){
#ifdef LG
freopen("1099.in" , "r" , stdin);
//freopen("1099.out" , "w" , stdout);
#endif
N = read();
int S = read();
; i < N ; i++){
int a = read() , b = read() , c = read();
addEd(a , b , c);
addEd(b , a , c);
}
dfs( , , );
int t = maxDir;
maxLen = ;
dfs(t , , );
getRoute(t , maxDir);
, q = , lenP = , dis = , lenQ = sum , maxAll = , ans = 0x7fffffff;
; i <= cntRoute ; i++){
Dfs(route[i][] , i , , );
maxAll = max(maxAll , maxL[i]);
}
do{
] <= S){
lenQ -= route[q][];
dis += route[q++][];
}
ans = min(ans , max(maxAll , max(lenP , lenQ)));
lenP += route[p][];
dis -= route[p++][];
}while(q < cntRoute);
cout << ans;
;
}
*树网的核
NOIP2008(clear)
//DP,设f[i][j][k]表示第一条路径走到(j,i-j),第二条路径走到(k,i-k)时的最大和,每一次枚举向右还是向下,注意路径不能相交
//当然写费用流也是可以的(逃
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll fast_read()
{
char c = getchar();
ll a = ;
;
while(!isdigit(c))
{
;
c = getchar();
}
) + (a << ) + c - ' , c = getchar();
return k ? -a : a;
}
inline void fast_print(ll x)
{
] , dirN = -;
) putchar('-') , x = -x;
, x /= ;
) putchar(');
) putchar(num[dirN--] + );
putchar('\n');
}
][] , ans[][][];
int main()
{
int M = fast_read() , N = fast_read();
; i <= M ; i++)
; j <= N ; j++) num[i][j] = fast_read();
; i <= N + M ; i++)
, i - M) ; k <= min(N , i - ) ; k++)
) ; l++)
{
ans[i][k][l] = max(ans[i - ][k][l] , max(ans[i - ][k][l - ] ,
max(ans[i - ][k - ][l - ] , ans[i - ][k - ][l]))) + (k - l ? num[i - k][k] + num[i - l][l] : num[i - k][k]);
}
fast_print(ans[N + M][N][N]);
;
}
传纸条
//按题意模拟
#include<bits/stdc++.h>
using namespace std;
];
bool ifZ(int a)
{
) return false;
; i * i <= a ; i++)
) return false;
return true;
}
int main()
{
ios::sync_with_stdio(false);
string s;
, minN = ;
cin >> s;
; i < s.size() ; i++)
maxN = max(maxN , ++num[s[i] - 'a']);
; i < ; i++)
if(num[i] && num[i] < minN) minN = num[i];
if(ifZ(maxN - minN)) cout << "Lucky Word" << endl << maxN - minN;
;
;
}
笨小猴
//爆搜、打表都可以
#include<bits/stdc++.h>
using namespace std;
inline int hcb(int a)
{
;
)
{
)
{
:
:
: sum += ;break;
: sum += ;break;
: sum += ;break;
: sum += ;break;
: sum += ;break;
;
}
a /= ;
}
switch(a)
{
:
:
: sum += ;break;
: sum += ;break;
: sum += ;break;
: sum += ;break;
: sum += ;break;
;
}
return sum;
}
int main()
{
ios::sync_with_stdio(false);
;
cin >> n;
n -= ;
; i <= ; i++)
; j++)
if(hcb(i) + hcb(j) + hcb(i + j) == n)
;
else cou++;
cout << cou;
;
}
火柴棒等式
//贪心地对第一个栈进行操作,如果后面有只能加入第一个栈的数字才考虑将当前数字加入第二个栈
#include<bits/stdc++.h>
#define LG
//This code is written by Itst
using namespace std;
inline int read(){
;
;
char c = getchar();
while(c != EOF && !isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(c != EOF && isdigit(c)){
a = (a << ) + (a << ) + (c ^ ');
c = getchar();
}
return f ? -a : a;
}
] , s2[] , num[] , top1 , top2 , cntStep , now;
];
];
int main(){
#ifdef LG
freopen("1155.in" , "r" , stdin);
//freopen("1155.out" , "w" , stdout);
#endif
int N = read();
s1[] = s2[] = ;
; i <= N ; i++)
num[i] = read();
; i <= N ; i++){
;
memset(vis , , sizeof(vis));
; j <= N ; j++)
if(num[j] > s2[top2]){
; f && k < num[i] ; k++)
if(!vis[k])
f = ;
break;
}
else
vis[num[j]] = ;
if(f && s1[top1] > num[i]){
s1[++top1] = num[i];
step[++cntStep] = 'a';
){
++now;
--top1;
step[++cntStep] = 'b';
}
}
else{
){
++now;
--top2;
step[++cntStep] = 'd';
}
if(s2[top2] < num[i]){
puts(");
;
}
s2[++top2] = num[i];
step[++cntStep] = 'c';
}
}
while(top1 || top2)
){
++now;
--top1;
step[++cntStep] = 'b';
}
else{
++now;
--top2;
step[++cntStep] = 'd';
}
; i <= cntStep ; i++){
putchar(step[i]);
putchar(' ');
}
;
}
*双栈排序
NOIP2009(clear)
//细节多得不行!!!
#include<bits/stdc++.h>
using namespace std;
] , dy[];
int main(){
ios::sync_with_stdio(false);
string s1 , s2 , s3;
cin >> s1 >> s2 >> s3;
; i < s1.size() ; i++)
{
|| dy[s2[i] - )
{
cout << "Failed";
;
}
mw[s1[i] - ;
dy[s2[i] - ;
}
; i < ; i++)
if(!mw[i] || !dy[i])
{
cout << "Failed";
;
}
; i < s3.size() ; i++)
cout << ();
;
}
潜伏者
//枚举质数,对于每个质数分类讨论考虑取值个数
#include<bits/stdc++.h>
using namespace std;
];
] , cnt;
inline int getNum(long long &a , int i){
;
){
a /= i;
cnt++;
}
return cnt;
}
inline int min(int a , int b){return a < b ? a : b;}
inline int max(int a , int b){return a > b ? a : b;}
int main(){
; i <= ; i++)
if(!prime[i]){
num[cnt++] = i;
; j++)
prime[i * j] = ;
}
long long l1 , r1 , l2 , r2 , N , a0 , a1 , b0 , b1;
for(scanf("%lld" , &N) ; N ; N--){
;
scanf("%lld%lld%lld%lld" , &a0 , &a1 , &b0 , &b1);
; i < cnt && a0 + a1 + b0 + b1 - && sum ; i++){
int f1 = getNum(a0 , num[i]) , f2 = getNum(a1 , num[i]);
;
else if(f1 > f2) l1 = r1 = f2;
;
f1 = getNum(b0 , num[i]); f2 = getNum(b1 , num[i]);
, r2 = f1;
;
else l2 = r2 = f2;
l1 = max(l1 , l2);
r1 = min(r1 , r2);
) sum = ;
sum *= (r1 - l1 + );
}
){
int f1 = getNum(b0 , a0), f2 = getNum(b1 , a0);
, r2 = f1;
;
else l2 = r2 = f2;
f2 = getNum(a1 , a0) , f1 = getNum(a0 , a0);
;
else if(f1 > f2) l1 = r1 = f2;
;
l1 = max(l1 , l2);
r1 = min(r1 , r2);
sum *= (r1 - l1 + );
}
){
int f1 = getNum(b0 , a1), f2 = getNum(b1 , a1);
, r2 = f1;
;
else l2 = r2 = f2;
f1 = getNum(a0 , a1) , f2 = getNum(a1 , a1);
;
else if(f1 > f2) l1 = r1 = f2;
;
l1 = max(l1 , l2);
r1 = min(r1 , r2);
sum *= (r1 - l1 + );
}
){
int f1 = getNum(a0 , b0) , f2 = getNum(a1 , b0);
;
else if(f1 > f2) l1 = r1 = f2;
;
f2 = getNum(b1 , b0); f1 = getNum(b0 , b0);
, r2 = f1;
;
else l2 = r2 = f2;
l1 = max(l1 , l2);
r1 = min(r1 , r2);
sum *= (r1 - l1 + );
}
){
int f1 = getNum(a0 , b1) , f2 = getNum(a1 , b1);
;
else if(f1 > f2) l1 = r1 = f2;
;
f1 = getNum(b0 , b1); f2 = getNum(b1 , b1);
, r2 = f1;
;
else l2 = r2 = f2;
l1 = max(l1 , l2);
r1 = min(r1 , r2);
sum *= (r1 - l1 + );
}
printf("%lld\n" , sum);
}
;
}
*Hankson的趣味题
//缩点+记忆化搜索
#include<bits/stdc++.h>
#define MAXN 100001
using namespace std;
inline int read(){
;
char c = getchar();
while(!isdigit(c)) c = getchar();
) + a + (c ^ ') , c = getchar();
return a;
}
inline int min(int a , int b){return a < b ? a : b;}
inline int max(int a , int b){return a > b ? a : b;}
vector < int > Ed[MAXN] , Ed_SCC[MAXN];
int Stack[MAXN] , inSCC[MAXN] , dfn[MAXN] , low[MAXN] , MAX[MAXN] , MIN[MAXN] , pri[MAXN];
int ts , N , M , head , num , ans;
bool vis[MAXN] , in[MAXN] , visSCC[MAXN];
void findSCC(int a){
Stack[++head] = a;
vis[a] = ;
dfn[a] = low[a] = ++ts;
; i < Ed[a].size() ; i++){
if(!vis[Ed[a][i]]) findSCC(Ed[a][i]);
else if(!in[Ed[a][i]]) continue;
low[a] = min(low[a] , low[Ed[a][i]]);
}
if(dfn[a] == low[a]){
num++;
do{
;
inSCC[Stack[head]] = num;
Ed_SCC[num].push_back(Stack[head]);
MAX[num] = max(MAX[num] , pri[Stack[head]]);
MIN[num] = min(MIN[num] , pri[Stack[head]]);
}while(Stack[head--] != a);
}
}
bool dfs(int a , int lowBuy){
if(in[a]) return visSCC[a];
;
;
lowBuy = min(lowBuy , MIN[a]);
; i < Ed_SCC[a].size() ; i++)
; j < Ed[Ed_SCC[a][i]].size() ; j++)
if(inSCC[Ed[Ed_SCC[a][i]][j]] != a)
if(dfs(inSCC[Ed[Ed_SCC[a][i]][j]] , lowBuy)){
visSCC[a] = ;
MAX[a] = max(MAX[a] , MAX[inSCC[Ed[Ed_SCC[a][i]][j]]]);
}
if(visSCC[a]){
ans = max(ans , MAX[a] - lowBuy);
;
}
;
}
int main(){
N = read();
M = read();
; i <= N ; i++) pri[i] = read();
while(M--){
int a = read() , b = read() , c = read();
Ed[a].push_back(b);
) Ed[b].push_back(a);
}
memset(MIN , 0x3f , sizeof(MIN));
; i <= N ; i++)
if(!vis[i]) findSCC(i);
dfs(inSCC[] , 0x3f3f3f3f);
cout << ans;
;
}
*最优贸易
//需要比较强的剪枝
#include<bits/stdc++.h>
#define K num[i][j].num
using namespace std;
;
struct kuai{
] , qz;
void init()
{
fs = ;
memset(vis , , );
}
};
kuai num[][];
inline void add(int i , int j);
inline void erase(int i , int j);
void dfs(int i , int j);
void find();
int main(){
; i < ; i++)
; j < ; j++)
{
num[i][j].init();
num[i][j].qz = - max(abs(i - ) , abs(j - ));
}
; i < ; i++)
; j < ; j++)
{
scanf("%d" , &K);
if(K)
add(i , j);
}
find();
cout << maxN;
;
}
inline void add(int i , int j)
{
; k < ; k++)
{
if(!num[i][k].vis[K]) num[i][k].fs--;
num[i][k].vis[K]++;
if(!num[k][j].vis[K]) num[k][j].fs--;
num[k][j].vis[K]++;
}
* ; m < i / * + ; m++)
* ; n < j / * + ; n++)
{
if(!num[m][n].vis[K]) num[m][n].fs--;
num[m][n].vis[K]++;
}
}
inline void erase(int i , int j)
{
; k < ; k++)
{
) num[i][k].fs++;
num[i][k].vis[K]--;
) num[k][j].fs++;
num[k][j].vis[K]--;
}
* ; m < i / * + ; m++)
* ; n < j / * + ; n++)
{
) num[m][n].fs++;
num[m][n].vis[K]--;
}
}
void dfs(int i , int j)
{
; k <= ; k++)
if(!num[i][j].vis[k])
{
K = k;
add(i , j);
find();
erase(i , j);
K = ;
}
}
void find()
{
, minX = , minY = ;
; i >= && min - ; i--)
; j >= && min - ; j--)
if(!K && !num[i][j].fs)
return;
else
if(min > num[i][j].fs && num[i][j].fs && !K)
{
min = num[i][j].fs;
minX = i;
minY = j;
}
)
{
;
; i < ; i++)
; j < ; j++)
numm += K * num[i][j].qz;
maxN = max(maxN , numm);
}
else
dfs(minX , minY);
}
*靶形数独
NOIP2010(clear)
//送分题
#include<bits/stdc++.h>
using namespace std;
];
int main()
{
, n , m;
for(cin >> m >> n ; n ; n--)
{
;
cin >> k;
; f && i < min(dirNum , m) ; i++)
;
if(f) num[dirNum++ % m] = k;
}
cout << dirNum;
;
}
机器翻译
//并查集or二分图
#include<bits/stdc++.h>
using namespace std;
inline int read(){
;
char c = getchar();
while(!isdigit(c)) c = getchar();
) + (a << ) + (c ^ ') , c = getchar();
return a;
}
struct ani{
][];
int* operator [](int a){return father[a];}
//0same,1dif
}ans[];
pair < int , int > find(int a , int b){
]][b][] ^ ans[a][b][]){
pair < ] , ans[a][b][]);
ans[a][b][] = t.first;
ans[a][b][] = t.second;
}
] , ans[a][b][]);
}
struct Ed{
int a , b , wei;
}now[];
bool cmp(Ed a , Ed b){
return a.wei > b.wei;
}
int main(){
int N = read() , M = read();
; i <= N ; i++)
; j ^ ; j++){
ans[i][j][] = i;
ans[i][j][] = j;
}
; i ^ M ; i++){
now[i].a = read();
now[i].b = read();
now[i].wei = read();
}
sort(now , now + M , cmp);
; i < M ; i++){
) == find(now[i].b , )){
cout << now[i].wei;
;
}
; j ^ ; j++){
pair < int , int > t1 = find(now[i].a , j) , t2 = find(now[i].b , !j);
ans[t1.first][t1.second][] = t2.first;
ans[t1.first][t1.second][] = t2.second;
//cout << t1.first << " " << t1.second << endl << t2.first << " " << t2.second << endl;
}
}
cout << ;
;
}
关押罪犯
//设f[i][j][k][l]为使用了i个1、j个2、k个3、l个4时的最大得分,随便转移,或者记忆化
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll fast_read()
{
char c = getchar();
ll a = ;
;
while(!isdigit(c))
{
;
c = getchar();
}
) + (a << ) + c - ' , c = getchar();
return k ? -a : a;
}
inline void fast_print(ll x)
{
] , dirN = -;
) putchar('-') , x = -x;
, x /= ;
) putchar(');
) putchar(num[dirN--] + );
putchar('\n');
}
] , kp[][][][] , pot[];
int main()
{
ll N = fast_read() , M = fast_read();
; i < N ; i++) score[i] = fast_read();
; i < M ; i++)
{
int q = fast_read();
pot[q]++;
}
; i <= pot[] ; i++)
; j <= pot[] ; j++)
; p <= pot[] ; p++)
; q <= pot[] ; q++)
{
: , j1 = j ? j - : , p1 = p ? p - : , q1 = q ? q - : ;
kp[i][j][p][q] = max(kp[i1][j][p][q] , max(kp[i][j1][p][q] , max(kp[i][j][p1][q] , kp[i][j][p][q1]))) + score[i + j * + p * + q * ];
}
fast_print(kp[pot[]][pot[]][pot[]][pot[]]);
;
}
乌龟棋
NOIP2011(clear)
//不要开10w*10w数组啊喂
#include<bits/stdc++.h>
using namespace std;
][];
int main()
{
std::ios::sync_with_stdio(false);
int n , a , b;
cin >> n;
; i < n ; i++)
cin >> c[i][] >> c[i][] >> c[i][] >> c[i][];
cin >> a >> b;
; i + ; i--)
] && a <= c[i][] + c[i][] && b >= c[i][] && b <= c[i][] + c[i][])
{
cout << i + ;
;
}
cout << -;
;
}
铺地毯
//将还没有一个在它后面的价格小于p的客栈的数量和已经有的客栈的数量统计下来,每一次来一个客栈更新一次并贡献答案
#include<bits/stdc++.h>
using namespace std;
inline long long read(){
;
char c = getchar();
while(!isdigit(c)) c = getchar();
) + (a << ) + (c ^ ') , c = getchar();
return a;
}
][];
int main(){
;
while(n--){
int a = read() , b = read();
if(b <= p)
; i ^ k ; i++){
num[i][] += num[i][];
num[i][] = ;
}
sum += num[a][];
]++;
]++;
}
cout << sum;
;
}
选择客栈
//搜索,(因为似乎数据保证刚好$N$步完成)所以相同色块一定不动;如果存在色块数量为1or2就剪枝;因为左移优先级低,所以通过左移交换两个块一定不优
#include<bits/stdc++.h>
//This code is written by Itst
using namespace std;
inline int read(){
;
;
char c = getchar();
while(c != EOF && !isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(c != EOF && isdigit(c)){
a = (a << ) + (a << ) + (c ^ ');
c = getchar();
}
return f ? -a : a;
}
][] = {,,,-,,,-,};
][] , N , now[][] , num[];
][];
void output(){
; i < N ; i++)
printf(] , now[i][] , now[i][]);
exit();
}
inline void drop(){
; i < ; i++)
; j < ; j++)
if(col[i][j]){
;
&& !col[i][p]){
col[i][p] = col[i][p + ];
col[i][p + ] = ;
p--;
}
}
}
inline bool search(){
;
memset(vis , , sizeof(vis));
; i < ; i++)
; j < && col[i][j] ; j++)
] && col[i][j] == col[i][j + ])
vis[i][j] = vis[i][j + ] = vis[i][j + ] = ;
; i < ; i++)
; j < ; j++)
][j] && col[i][j] == col[i + ][j])
vis[i][j] = vis[i + ][j] = vis[i + ][j] = ;
; i < ; i++)
; j < ; j++)
if(vis[i][j]){
num[col[i][j]]--;
f = ;
col[i][j] = ;
}
return f;
}
inline void maintain(){
do{
drop();
}while(search());
}
void dfs(int step){
;
; i <= ; i++)
|| num[i] == )
return;
else
if(num[i])
cnt = ;
if(!cnt){
output();
return;
}
if(step == N)
return;
][] , tnum[];
memcpy(t , col , sizeof(col));
memcpy(tnum , num , sizeof(num));
; i < ; i++)
; j < ; j++)
; k >= - ; k -= )
&& i + k < && col[i][j] && col[i][j] != col[i + k][j] && (k == || !col[i + k][j])){
swap(col[i][j] , col[i + k][j]);
now[step][] = i;
now[step][] = j;
now[step][] = k;
maintain();
dfs(step + );
memcpy(col , t , sizeof(col));
memcpy(num , tnum , sizeof(tnum));
}
}
int main(){
#ifdef LG
freopen("1312.in" , "r" , stdin);
//freopen("1312.out" , "w" , stdout);
#endif
N = read();
; i < ; i++)
; j < ; j++)
if(!(col[i][j] = read()))
break;
else
++num[col[i][j]];
dfs();
puts("-1");
;
}
*Mayan游戏
//二项式定理
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll fast_read()
{
char c = getchar();
ll a = ;
;
while(!isdigit(c))
{
;
c = getchar();
}
) + (a << ) + c - ' , c = getchar();
return k ? -a : a;
}
inline void fast_print(ll x)
{
] , dirN = -;
) putchar('-') , x = -x;
, x /= ;
) putchar(');
) putchar(num[dirN--] + );
}
ll square[][] = {{}};
int main()
{
ll a = fast_read() , b = fast_read() , k = fast_read() , n = fast_read() , m = fast_read() , num = ;
; i <= k ; i++)
{
square[i][] = ;
; j <= i ; j++) square[i][j] = (square[i - ][j] + square[i - ][j - ]) % ;
}
; i < n ; i++) num = num * a % ;
; i < m ; i++) num = num * b % ;
fast_print(num * square[k][n] % );
;
}
计算系数
//二分+前缀和
#include<bits/stdc++.h>
#define MAXN 200001
#define ll long long
using namespace std;
inline ll read(){
ll a = ;
char c = getchar();
while(!isdigit(c)) c = getchar();
) + (a << ) + (c ^ ') , c = getchar();
return a;
}
ll w[MAXN] , v[MAXN] , num[MAXN] , allV[MAXN] , N , M , S , qj[MAXN][];
ll check(ll a){
; i <= N ; i++){
num[i] = (w[i] >= a) + num[i - ];
allV[i] = (w[i] >= a ? v[i] : ) + allV[i - ];
}
;
; i <= M ; i++)
sum += (num[qj[i][]] - num[qj[i][] - ]) * (allV[qj[i][]] - allV[qj[i][] - ]);
return sum;
}
inline ll abss(ll a){ ? a : -a;}
int main(){
, minW = 0x3f3f3f3f;
N = read(); M = read(); S = read();
; i <= N ; i++){
w[i] = read() , v[i] = read();
if(maxW < w[i]) maxW = w[i];
if(minW > w[i]) minW = w[i];
}
; i <= M ; i++)
qj[i][] = read() , qj[i][] = read();
){
ll mid = maxW + minW >> ;
if(check(mid) >= S) minW = mid;
else maxW = mid;
}
cout << min(abss(check(minW) - S) , abss(S - check(maxW)));
;
}
*聪明的质检员
//每一次贪心地选择能够影响更多人的地方
#include<bits/stdc++.h>
#define MAXN 1010
using namespace std;
int far[MAXN] , down[MAXN] , D[MAXN] , maxD[MAXN] , minT[MAXN] , N , M , K;
long long ans;
inline void get(){
;
; i <= N ; i++){
ans += time * down[i];
time = max(time , maxD[i]) + D[i];
}
}
inline void work(){
far[N] = N;
; i ; i--)
far[i] = minT[i + ] > maxD[i + ] ? far[i + ] : i + ;
, maxDir = ;
; i < N ; i++)
if(D[i] && maxN < down[far[i]] - down[i]){
maxN = down[far[i]] - down[i];
maxDir = i;
}
D[maxDir]--;
ans -= maxN;
; i <= far[maxDir] ; i++)
minT[i] = max(minT[i - ] , maxD[i - ]) + D[i - ];
}
int main(){
cin >> N >> M >> K;
; i < N ; i++)
cin >> D[i];
; i <= M ; i++){
int T , A , B;
cin >> T >> A >> B;
maxD[A] = max(maxD[A] , T);
down[B]++;
ans -= T;
}
get();
; i <= N ; i++){
down[i] += down[i - ];
minT[i] = max(minT[i - ] , maxD[i - ]) + D[i - ];
}
while(K--)
work();
cout << ans;
;
}
*观光公交
NOIP2012(clear)
//直接模拟
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll fast_read()
{
char c = getchar();
ll a = ;
;
while(!isdigit(c))
{
;
c = getchar();
}
) + (a << ) + c - ' , c = getchar();
return k ? -a : a;
}
inline void fast_print(ll x)
{
] , dirN = -;
) putchar('-') , x = -x;
, x /= ;
) putchar(');
) putchar(num[dirN--] + );
putchar('\n');
}
int main()
{
string a , b;
cin >> a >> b;
, la = a.size() , lb = b.size();
; i < lb ; i++ , dirA++)
{
char c = a[dirA % la];
while(c != 'a' && c-- != 'A')
{
b[i]--;
|| b[i] == ) b[i] += ;
}
}
cout << b;
;
}
Vigenère 密码
//根据邻项交换推贪心策略,排序后算答案
#include<bits/stdc++.h>
using namespace std;
] , allSum[] , maxN[];
struct p{
int l , r;
}ans[];
bool cmp(p a , p b)
{
return a.l * a.r < b.l * b.r;
}
void comp()
{
] < maxN[]) return;
] == maxN[])
] ; i ; i--)
if(d[i] < maxN[i]) return;
else if(d[i] > maxN[i]) break;
; i <= d[] ; i++) maxN[i] = d[i];
}
inline int fast_read()
{
char ch = getchar();
, k = ;
while(!isdigit(ch)){
;
ch = getchar();
}
) + (a << ) + ch - ' , ch = getchar();
return a;
}
int main()
{
int n = fast_read();
; i <= n ; i++)
ans[i].l = fast_read() , ans[i].r = fast_read();
].l)
{
allSum[++allSum[]] = ans[].l % ;
ans[].l /= ;
}
sort(ans + , ans + n + , cmp);
; i <= n ; i++)
{
memset(d , , sizeof(d));
, sum = ;
] ; j ; j--)
{
sum = sum * + allSum[j];
if(sum >= ans[i].r)
{
d[j] = sum / ans[i].r;
sum %= ans[i].r;
if(!f)
{
f = ;
d[] = j;
}
}
}
comp();
; j <= allSum[] ; j++)
allSum[j] *= ans[i].l;
; j <= allSum[] ; j++)
)
{
allSum[j + ] += allSum[j] / ;
allSum[j] %= ;
]) allSum[]++;
}
}
] ; i ; i--) cout << maxN[i];
;
}
*国王游戏
//拓欧裸题
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll fast_read()
{
char c = getchar();
ll a = ;
;
while(!isdigit(c))
{
;
c = getchar();
}
) + (a << ) + c - ' , c = getchar();
return k ? -a : a;
}
void exGcd(int a , int b , int &x , int &y)
{
) x = / a , y = ;
else
{
exGcd(b , a % b , x , y);
int t = x;
x = y;
y = t - a / b * y;
}
}
int main()
{
int a = fast_read() , b = fast_read() , c , d;
exGcd(a , -b , c , d);
) c += b;
cout << c % b;
;
}
*同余方程
//线段树这种常数极大的东西在CCF老人机上一定会被卡常数成95pts
#include<bits/stdc++.h>
using namespace std;
];
inline int read(){
;
char c = getchar();
while(!isdigit(c)) c = getchar();
) + (a << ) + (c ^ ') , c = getchar();
return a;
}
int cou , N;
inline int min(int a , int b){
return a < b ? a : b;
}
struct node{
node *left , *right;
int start , end , minN , minus_tag;
node(){
if(_s == _e) minN = read();
else{
left = );
right = ) + , _e);
minN = min(left->minN , right->minN);
}
}
void change(int _s , int _e , int num){
if(_s == start && _e == end)
){
cout << - << endl << cou;
exit();
}
else{
minN += num;
minus_tag += num;
return;
}
left->minN += minus_tag;
right->minN += minus_tag;
left->minus_tag += minus_tag;
right->minus_tag += minus_tag;
minus_tag = ;
) left->change(_s , _e , num);
) right->change(_s , _e , num);
else{
left->change(_s , start + end >> , num);
right->change((start + end >> ) + , _e , num);
}
minN = min(left->minN , right->minN);
}
}*Tree;
int main(){
int N = read() , K = read();
Tree = , N);
; cou <= K ; cou++)
{
int a = read() , b = read() , c = read();
Tree->change(b , c , -a);
}
cout << ;
;
}
借教室
NOIP2013(clear)
//快速幂裸题
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll fast_read()
{
char c = getchar();
ll a = ;
;
while(!isdigit(c))
{
;
c = getchar();
}
) + (a << ) + c - ' , c = getchar();
return k ? -a : a;
}
inline void fast_print(ll x)
{
] , dirN = -;
) putchar('-') , x = -x;
, x /= ;
) putchar(');
) putchar(num[dirN--] + );
}
] , circle;
inline int fast_mi(int a)
{
ll num = % circle , add = ;
while(a)
{
) add = add * num % circle;
a >>= ;
num = num * num % circle;
}
return add;
}
int main()
{
int k = fast_read() , t = fast_read();
])
{
num[circle] = t;
t = (num[circle++] + m) % n;
}
fast_print(num[fast_mi(k)]);
;
}
转圈游戏
//离散化+逆序对(显然两个相对大小顺序一样的时候答案最优)
#include<bits/stdc++.h>
#define MAXN 100001
using namespace std;
inline int read(){
;
char c = getchar();
while(!isdigit(c)) c = getchar();
) + (a << ) + (c ^ ') , c = getchar();
return a;
}
int num1[MAXN] , num2[MAXN] , lsh1[MAXN] , lsh2[MAXN] , tree[MAXN] , N = read();
map < int , int > n1 , to2 , n2;
inline ? a : -a;}
inline int lowbit(int a){return a & -a;}
inline int getSum(int a){
;
while(a){
sum += tree[a];
a -= lowbit(a);
}
return sum;
}
inline void add(int a){
while(a <= N){
tree[a]++;
a += lowbit(a);
}
}
int main(){
;
; i < N ; i++) num1[i] = lsh1[i] = read();
; i < N ; i++) num2[i] = lsh2[i] = read();
sort(lsh1 , lsh1 + N);
; i < N ; i++) n1[lsh1[i]] = i + ;
; i < N ; i++) to2[n1.find(num1[i])->second] = i + ;
sort(lsh2 , lsh2 + N);
; i < N ; i++) n2[lsh2[i]] = i + ;
; i >= ; i--){
int t = to2.find(n2.find(num2[i])->second)->second;
sum += getSum(t - );
add(t);
}
cout << sum % ;
;
}
*火柴排队
//维护递增的单调栈
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll fast_read()
{
char c = getchar();
ll a = ;
;
while(!isdigit(c))
{
;
c = getchar();
}
) + (a << ) + c - ' , c = getchar();
return k ? -a : a;
}
inline void fast_print(ll x)
{
] , dirN = -;
) putchar('-') , x = -x;
, x /= ;
) putchar(');
) putchar(num[dirN--] + );
}
int sum , a;
int main()
{
for(int n = fast_read() ; n ; n--)
{
int b = fast_read();
if(a > b) sum += a - b;
a = b;
}
fast_print(sum + a);
;
}
积木大赛
//DP
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll fast_read()
{
char c = getchar();
ll a = ;
;
while(!isdigit(c))
{
;
c = getchar();
}
) + (a << ) + c - ' , c = getchar();
return k ? -a : a;
}
inline void fast_print(ll x)
{
] , dirN = -;
) putchar('-') , x = -x;
, x /= ;
) putchar(');
) putchar(num[dirN--] + );
}
] , h2[];
int main()
{
, dir2 = ;
h2[] = h1[] = fast_read();
; i <= n ; i++)
{
int a = fast_read();
) % == && h1[dir1] != a)
h1[++dir1] = a;
else h1[dir1] = a;
) % == && h2[dir2] != a)
h2[++dir2] = a;
else h2[dir2] = a;
}
fast_print(max(dir1 , dir2));
;
}
花匠
NOIP2014(clear)
//模拟
#include<bits/stdc++.h>
using namespace std;
][] , Na[] , Nb[];
int main()
{
ios::sync_with_stdio(false);
sf[][] = sf[][] = sf[][] = sf[][] = sf[][] = -;
sf[][] = sf[][] = sf[][] = sf[][] = sf[][] = ;
cin >> N >> a >> b;
; i < a ; i++) cin >> Na[i];
; i < b ; i++) cin >> Nb[i];
while(N--)
{
if(Na[dirA] - Nb[dirB])
if(sf[Na[dirA]][Nb[dirB]])
) sumA++;
else sumB++;
) sumB++;
else sumA++;
dirA = (dirA + ) % a;
dirB = (dirB + ) % b;
}
cout << sumA << " " << sumB;
;
}
生活大爆炸版石头剪刀布
//一棵树上只有可能出现:爷爷和孙子(?)和同父兄弟这两种情况会产生联合权值,第二种权值的计算需要优化成O(n)
#include<bits/stdc++.h>
using namespace std;
inline int read(){
register ;
register char c = getchar();
while(!isdigit(c)) c = getchar();
) + (a << ) + (c ^ ') , c = getchar();
return a;
}
inline int max(int a , int b){
return a > b ? a : b;
}
struct Edge{
int upEd , end;
}now[];
] , Las[];
];
struct node{
int num , father , grandpa;
}ans;
int main(){
;
register ;
; i ^ n ; i++){
a = read();
b = read();
now[(i << ) - ].end = b;
now[(i << ) - ].upEd = Las[a];
Las[a] = (i << ) - ;
now[i << ].end = a;
now[i << ].upEd = Las[b];
Las[b] = i << ;
}
; i ^ n + ; i++) num[i] = read();
queue < node > q;
ans.num = ;
ans.father = ans.grandpa = ;
q.push(ans);
while(!q.empty()){
ans = q.front();
q.pop();
if(ans.grandpa){
sum += num[ans.grandpa] * num[ans.num] << ;
maxN = max(maxN , num[ans.grandpa] * num[ans.num]);
}
vis[ans.num] = ;
node ans1;
ans1.grandpa = ans.father;
ans1.father = ans.num;
register , maxM2 = ;
, sumN = ;
for(register int i = Las[ans.num] ; i ; i = now[i].upEd)
if(!vis[now[i].end]){
if(num[now[i].end] > maxM1){
maxM2 = maxM1;
maxM1 = num[now[i].end];
}
else if(num[now[i].end] > maxM2) maxM2 = num[now[i].end];
sumM += num[ans1.num = now[i].end];
sumN += num[now[i].end] * num[now[i].end];
q.push(ans1);
}
maxN = max(maxN , maxM1 * maxM2);
sum += sumM * sumM - sumN;
}
printf();
;
}
*联合权值
//DP
#include<bits/stdc++.h>
using namespace std;
inline int read(){
;
char c = getchar();
while(!isdigit(c))
c = getchar();
while(isdigit(c)){
a = (a << ) + (a << ) + (c ^ ');
c = getchar();
}
return a;
}
inline int min(int a , int b){
return a < b ? a : b;
}
struct gd{
int P , L , R;
}now[];
bool cmp(gd a , gd b){
return a.P < b.P;
}
][] , minN[][];
int main(){
;
cin >> N >> M >> K;
; i <= N ; i++){
jump[i][] = read();
jump[i][] = read();
}
; i <= K ; i++){
now[i].P = read();
now[i].L = read();
now[i].R = read();
}
sort(now + , now + K + , cmp);
; i <= N ; i++){
memset(minN[i & ] , ]));
; j <= M ; j++)
minN[i & ][j + jump[i][] > M ? M : j + jump[i][]] = min(minN[i & ][j + jump[i][] > M ? M : j + jump[i][]] , min(minN[i & ][j] , minN[i & ^ ][j]) + );
] + ; j <= M ; j++)
minN[i & ][j - jump[i][]] = min(minN[i & ][j - jump[i][]] , minN[i & ^ ][j]);
if(now[dir].P == i){
; j <= now[dir].L ; j++)
minN[i & ][j] = 0x3f3f3f3f;
for(int j = now[dir].R ; j <= M ; j++)
minN[i & ][j] = 0x3f3f3f3f;
;
; j < now[dir].R && !f ; j++)
][j] != 0x3f3f3f3f)
f = ;
if(!f){
cout << << endl << dir - ;
;
}
dir++;
}
}
int ans = 0x3f3f3f3f;
; i <= M ; i++)
ans = min(ans , minN[N & ][i]);
cout << << endl << ans;
;
}
*飞扬的小鸟
//乱搞
#include<bits/stdc++.h>
using namespace std;
][];
int main(){
ios::sync_with_stdio(false);
, d , n;
;
cin >> d >> n;
; i < n ; i++)
{
int a , b , c;
cin >> a >> b >> c;
m[a][b] = c;
}
; i < ; i++)
; j < ; j++)
{
;
) ; k <= i + d ; k++)
) ; p <= j + d ; p++)
num += m[k][p];
if(num > maxN){
maxN = num;
cou = ;
}
else if(num == maxN) cou++;
}
cout << cou << " " << maxN;
;
}
无线网络发射器选址
//每一次预处理出无法到达终点的点并影响可以到达的点,然后最短路
#include<bits/stdc++.h>
using namespace std;
inline int read(){
;
char c = getchar();
while(!isdigit(c)) c = getchar();
) + (a << ) + (c ^ ') , c = getchar();
return a;
}
vector < ] , FanEd[];
] , vis2[];
int main(){
ios::sync_with_stdio();cin.tie();cout.tie();
int n = read() , m = read();
while(m--){
int a = read() , b = read();
Ed[a].push_back(b);
FanEd[b].push_back(a);
}
; i <= n ; i++) vis2[i] = ;
int st = read() , end = read();
vis[end] = ;
queue < int > q1;
q1.push(end);
while(!q1.empty()){
int t = q1.front();
q1.pop();
; i ^ FanEd[t].size() ; i++)
if(!vis[FanEd[t][i]]){
vis[FanEd[t][i]] = ;
q1.push(FanEd[t][i]);
}
}
; i <= n ; i++)
if(!vis[i]){
vis2[i] = ;
; j ^ FanEd[i].size() ; j++)
vis2[FanEd[i][j]] = ;
}
if(!vis2[st]){
cout << -;
;
}
queue < pair < int , int > > q;
q.push(make_pair(st , ));
while(!q.empty()){
pair < int , int > t = q.front();
q.pop();
; i ^ Ed[t.first].size() ; i++)
if(vis2[Ed[t.first][i]]){
vis2[Ed[t.first][i]] = ;
if(Ed[t.first][i] == end){
cout << t.second + ;
;
}
q.push(make_pair(Ed[t.first][i] , t.second + ));
}
}
cout << -;
;
}
寻找道路
//998244353真是个好质数
#include<bits/stdc++.h>
#define MOD 998244353
#define ll long long
using namespace std;
inline ll read(){
ll a = ;
char c = getchar();
;
while(!isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(isdigit(c)){
a = ((a << ) + (a << ) + (c ^ ')) % MOD;
c = getchar();
}
return f ? -a : a;
}
];
inline void print(int a){
;
while(a){
output[dirN++] = a % ;
a /= ;
}
if(!dirN)
putchar(');
while(dirN)
putchar(output[--dirN] + );
putchar('\n');
}
] , num[] , n , m;
inline void calc(int dir){
ll sum = num[n];
; i >= ; i--)
sum = (sum * dir + num[i]) % MOD;
if(!sum)
ans[++ans[]] = dir;
}
int main(){
n = read();
m = read();
; i <= n ; i++)
num[i] = read();
; i <= m ; i++)
calc(i);
; i <= ans[] ; i++)
print(ans[i]);
;
}
*解方程
NOIP2015(clear)
//模拟
#include<bits/stdc++.h>
using namespace std;
][];
int main()
{
int N;
cin >> N;
, j = + N / ;
num[i][j] = ;
; k <= N * N ; k++)
{
&& j == N) i++;
){
i = N;
j++;
}
else if(j == N){
j = ;
i--;
}][j + ]){
i--;
j++;
}
else i++;
num[i][j] = k;
}
; i <= N ; i++)
{
; j <= N ; j++)
cout << num[i][j] << " ";
cout << endl;
}
;
}
神奇的幻方
//tarjan可以用来判环长哦!
//这下面是一个古老的Kosaraju
#include<bits/stdc++.h>
#define ll long long
#define MAXN 200001
using namespace std;
inline ll fast_read()
{
char c = getchar();
ll a = ;
;
while(!isdigit(c))
{
;
c = getchar();
}
) + (a << ) + c - ' , c = getchar();
return k ? -a : a;
}
inline void fast_print(ll x)
{
] , dirN = -;
) putchar('-') , x = -x;
, x /= ;
) putchar(');
) putchar(num[dirN--] + );
}
int num[MAXN] , fanNum[MAXN] , zhan[MAXN] , minN = MAXN , N = fast_read() , dirZ;
bool vis[MAXN];
struct edge{
int end , upEd;
void init(int a , int b)
{
upEd = fanNum[a];
fanNum[a] = end = b;
}
}ans[MAXN];
void fanDfs(int k)
{
vis[k] = ;
for(int i = fanNum[k] ; i ; i = ans[i].upEd)
if(!vis[ans[i].end]) fanDfs(ans[i].end);
zhan[dirZ++] = k;
}
int dfs(int k)
{
vis[k] = ;
+ dfs(num[k]);
;
}
int main()
{
; i <= N ; i++)
{
num[i] = fast_read();
if(i == num[i]) {
cout << ;
;
}
ans[i].init(num[i] , i);
}
; i <= N ; i++)
if(!vis[i]) fanDfs(i);
memset(vis , , sizeof(vis));
; dirZ--)
if(!vis[zhan[dirZ]])
{
int k = dfs(zhan[dirZ]);
) minN = min(minN , k);
}
fast_print(minN);
;
}
信息传递
//搜顺子,散排直接DP
#include<bits/stdc++.h>
//This code is written by Itst
using namespace std;
inline int read(){
;
;
char c = getchar();
while(c != EOF && !isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(c != EOF && isdigit(c)){
a = (a << ) + (a << ) + (c ^ ');
c = getchar();
}
return f ? -a : a;
}
] , gui[] , dp[][][][][] , ans;
inline void sub(int step){
;
] = {};
; i <= ; i++)
++num[pot[i]];
] && gui[]){
ifGui = ;
num[] += ;
}
else
] + gui[])
num[]++;
ans = min(ans , dp[num[]][num[]][num[]][num[]][ifGui] + step);
}
void dfs(int now , int step){
if(step > ans)
return;
){
sub(step);
return;
}
&& pot[now + ] >= ){
pot[now] -= ;
;
&& pot[i] >= ){
pot[i++] -= ;
dfs(now , step + );
}
while(--i >= now)
pot[i] += ;
}
&& pot[now + ] >= && pot[now + ] >= ){
pot[now] -= ;
pot[now + ] -= ;
;
&& pot[i] >= ){
pot[i++] -= ;
dfs(now , step + );
}
while(--i >= now)
pot[i] += ;
}
int i = now;
while(pot[i]){
)
break;
--pot[i++];
)
dfs(now , step + );
}
while(--i >= now)
++pot[i];
dfs(now + , step);
}
void init_dp(){
; m <= ; m++)
; k + m <= ; k++)
; j + k + m <= ; j++)
; i + j + k + m <= ; i++)
; i + j * + k * + m * <= && n <= && (n == || i >= ) ; n++)
if(i + j + k + m){
] = {i , j , k , m};
if(n)
dp[i][j][k][m][n] = min(dp[i][j][k][m][n] , dp[i - ][j][k][m][]);
if(m){
--num[];
; p <= ; p++)
if(num[p]){
--num[p];
if(p)
++num[p - ];
; q <= ; q++)
if(num[q]){
--num[q];
if(q)
++num[q - ];
dp[i][j][k][m][n] = min(dp[i][j][k][m][n] , dp[num[]][num[]][num[]][num[]][num[] >= && n]);
if(q)
--num[q - ];
++num[q];
}
++num[p];
if(p)
--num[p - ];
}
; p <= ; p++)
if(num[p]){
--num[p];
)
++num[p - ];
; q <= ; q++)
if(num[q]){
--num[q];
)
++num[q - ];
dp[i][j][k][m][n] = min(dp[i][j][k][m][n] , dp[num[]][num[]][num[]][num[]][num[] >= && n]);
)
--num[q - ];
++num[q];
}
++num[p];
)
--num[p - ];
}
++num[];
}
; a <= ; a++)
if(num[a]){
--num[a];
)
++num[];
; p <= ; p++)
if(num[p]){
--num[p];
if(p)
++num[p - ];
dp[i][j][k][m][n] = min(dp[i][j][k][m][n] , dp[num[]][num[]][num[]][num[]][num[] >= && n]);
if(p)
--num[p - ];
++num[p];
}
; p <= ; p++)
if(num[p]){
--num[p];
)
++num[p - ];
dp[i][j][k][m][n] = min(dp[i][j][k][m][n] , dp[num[]][num[]][num[]][num[]][num[] >= && n]);
++num[p];
)
--num[p - ];
}
)
--num[];
++num[a];
}
; p ; p--)
; q <= ; ++q)
if(num[q]){
--num[q];
if(q >= p)
++num[q - p];
dp[i][j][k][m][n] = min(dp[i][j][k][m][n] , dp[num[]][num[]][num[]][num[]][num[] >= && n]);
if(q >= p)
--num[q - p];
++num[q];
}
++dp[i][j][k][m][n];
}
}
int main(){
#ifdef LG
freopen("2668.in" , "r" , stdin);
//freopen("2668.out" , "w" , stdout);
#endif
memset(dp , 0x3f , sizeof(dp));
dp[][][][][] = ;
init_dp();
int T = read() , N = read();
; i <= T ; i++){
memset(pot , , sizeof(pot));
gui[] = gui[] = ;
ans = 0x7fffffff;
; j <= N ; j++){
int a = read();
if(a){
++pot[a <= ? a + : a - ];
read();
}
else
++gui[read()];
}
dfs( , );
printf("%d\n" , ans);
}
;
}
*斗地主
//二分+贪心
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll fast_read()
{
char c = getchar();
ll a = ;
;
while(!isdigit(c))
{
;
c = getchar();
}
) + (a << ) + c - ' , c = getchar();
return k ? -a : a;
}
inline void fast_print(ll x)
{
] , dirN = -;
) putchar('-') , x = -x;
, x /= ;
) putchar(');
) putchar(num[dirN--] + );
}
];
int main()
{
, t = L + ;
num[M + ] = L;
; i <= M ; i++) num[i] = fast_read();
)
{
, cou = , befL = ;
; i <= M + ; i++)
if(num[i] - befL < mid) cou++;
else befL = num[i];
if(cou > N) t = mid;
else h = mid;
}
fast_print(h);
;
}
跳石头
//DP
#include<bits/stdc++.h>
#define MOD 1000000007
using namespace std;
][][];
vector < ];
int main(){
int N , M , K;
string s , cmp;
cin >> N >> M >> K >> s >> cmp;
bp[][][] = ;
; i >= ; i--)
v[cmp[i] - 'a'].push_back(i);
; i < N ; i++){
; j <= M ; j++)
; k <= K ; k++)
bp[][j][k] = (bp[][j][k] + bp[][j][k]) % MOD;
memcpy(bp[] , bp[] , ]));
memset(bp[] , , ]));
; j < v[s[i] - 'a'].size() ; j++)
for(int k = K ; k ; k--)
bp[][v[s[i] - ][k] = ((bp[][v[s[i] - ][v[s[i] - ]) % MOD + bp[][v[s[i] - ]) % MOD;
}
cout << ((bp[][M][K] + bp[][M][K]) % MOD + bp[][M][K]) % MOD;
;
}
子串
//删掉一条边的影响一定只会在前i条路径上(i极大),所以从大到小在树上加边,每一次找到在所有最长的路径上的边中权值最大的边尝试删除。
#include<bits/stdc++.h>
#define MAXN 300002
#define l(x) Tree[x].l
#define r(x) Tree[x].r
#define sum(x) Tree[x].sum
#define mark(x) Tree[x].mark
#define mid(x) (Tree[x].l + Tree[x].r >> 1)
#define maxMark(dir) Tree[dir].maxMark
#define maxNum(dir) Tree[dir].maxNum
using namespace std;
struct node{
int l , r , sum , mark , maxMark , maxNum;
}Tree[MAXN << ];
struct Edge{
int end , w , upEd;
}Ed[MAXN << ];
struct route{
int start , end , w;
}Now[MAXN];
int head[MAXN] , val[MAXN] , size[MAXN] , fa[MAXN] , son[MAXN] , dep[MAXN];
int N , M , cntEd , ts , top[MAXN] , ind[MAXN] , rk[MAXN];
bool cmp(route a , route b){
return a.w > b.w;
}
inline int max(int a , int b){
return a > b ? a : b;
}
inline void addEd(int a , int b , int c){
Ed[++cntEd].end = b;
Ed[cntEd].w = c;
Ed[cntEd].upEd = head[a];
head[a] = cntEd;
}
void dfs1(int dir , int father , int v){
val[dir] = v;
size[dir] = ;
dep[dir] = dep[fa[dir] = father] + ;
for(int i = head[dir] ; i ; i = Ed[i].upEd)
if(fa[dir] != Ed[i].end){
dfs1(Ed[i].end , dir , Ed[i].w);
size[dir] += size[Ed[i].end];
if(size[son[dir]] < size[Ed[i].end])
son[dir] = Ed[i].end;
}
}
void dfs2(int dir , int t){
top[dir] = t;
rk[ind[dir] = ++ts] = dir;
if(!son[dir])
return;
dfs2(son[dir] , t);
for(int i = head[dir] ; i ; i = Ed[i].upEd)
if(Ed[i].end != son[dir] && Ed[i].end != fa[dir])
dfs2(Ed[i].end , Ed[i].end);
}
inline void pushup(int dir , int maxN){
) , maxMark(dir << | )))
maxNum(dir) = max(maxNum(dir) , maxN);
else{
maxMark(dir) = max(maxMark(dir << ) , maxMark(dir << | ));
maxNum(dir) = maxN;
}
}
inline void pushdown(int dir){
mark(dir << ) += mark(dir);
mark(dir << | ) += mark(dir);
maxMark(dir << ) += mark(dir);
maxMark(dir << | ) += mark(dir);
mark(dir) = ;
}
void init(int l , int r , int dir){
l(dir) = l;
r(dir) = r;
if(l == r)
sum(dir) = maxNum(dir) = val[rk[l]];
else{
init(l , mid(dir) , dir << );
init(mid(dir) + , r , dir << | );
sum(dir) = sum(dir << ) + sum(dir << | );
maxNum(dir) = max(maxNum(dir << ) , maxNum(dir << | ));
}
}
int getSum(int l , int r , int dir){
if(l(dir) >= l && r(dir) <= r)
return sum(dir);
;
if(l <= mid(dir))
sum += getSum(l , r , dir << );
if(r > mid(dir))
sum += getSum(l , r , dir << | );
return sum;
}
int getMark(int l , int r , int dir , int now){
if(l(dir) >= l && r(dir) <= r){
mark(dir)++;
;
}
pushdown(dir);
;
if(l <= mid(dir))
maxN = max(maxN , getMark(l , r , dir << , now));
if(r > mid(dir))
maxN = max(maxN , getMark(l , r , dir << | , now));
if(maxN)
pushup(dir , maxN);
return maxN;
}
inline void work1(int dir){
int x = Now[dir].start , y = Now[dir].end , tx = top[x] , ty = top[y];
while(tx != ty)
if(dep[tx] >= dep[ty]){
Now[dir].w += getSum(ind[tx] , ind[x] , );
x = fa[tx];
tx = top[x];
}
else{
Now[dir].w += getSum(ind[ty] , ind[y] , );
y = fa[ty];
ty = top[y];
}
if(ind[x] < ind[y])
Now[dir].w += getSum(ind[x] + , ind[y] , );
if(ind[x] > ind[y])
Now[dir].w += getSum(ind[y] + , ind[x] , );
}
inline int work2(int dir){
;
while(tx != ty)
if(dep[tx] >= dep[ty]){
maxN = max(maxN , getMark(ind[tx] , ind[x] , , dir));
x = fa[tx];
tx = top[x];
}
else{
maxN = max(maxN , getMark(ind[ty] , ind[y] , , dir));
y = fa[ty];
ty = top[y];
}
if(ind[x] < ind[y])
maxN = max(maxN , getMark(ind[x] + , ind[y] , , dir));
if(ind[x] > ind[y])
maxN = max(maxN , getMark(ind[y] + , ind[x] , , dir));
return maxN;
}
int main(){
srand((unsigned)time());
scanf("%d%d" , &N , &M);
; i < N ; i++){
int a , b , c;
scanf("%d%d%d" , &a , &b , &c);
addEd(a , b , c);
addEd(b , a , c);
}
;
dfs1(S , , );
dfs2(S , S);
init( , N , );
; i <= M ; i++){
scanf("%d%d" , &Now[i].start , &Now[i].end);
work1(i);
}
sort(Now + , Now + M + , cmp);
, minN = ;
while(dir <= M){
int t = work2(dir);
].w <= Now[].w - t){
minN = min(minN , Now[].w - t);
break;
}
minN = Now[dir + ].w;
dir++;
}
cout << minN;
;
}
*运输计划
NOIP2016(clear)
//有点绕的模拟
#include<bits/stdc++.h>
using namespace std;
];
];
int main()
{
ios::sync_with_stdio(false);
;
cin >> n >> m;
; i < n ; i++) cin >> cx[i] >> name[i];
while(m)
{
int a , b;
cin >> a >> b;
) dir = (dir + b) % n;
else dir = (dir - b + n) % n;
m--;
}
cout << name[dir];
;
}
玩具谜题
//期望DP
#include<bits/stdc++.h>
#define MAXN 2001
using namespace std;
] , gl[MAXN];
] , route[][] , n , m , v , e;
inline double calc(int dir , bool f1 , bool f2){
;
; i <= f1 ; i++)
; j <= f2 ; j++)
sum += route[room[dir - ][i]][room[dir][j]] * (f1 ? (i ? gl[dir - ] : - gl[dir - ]) : ) * (f2 ? (j ? gl[dir] : - gl[dir]) : );
return sum;
}
int main(){
ios::sync_with_stdio();
cin.tie();
cout.tie();
cin >> n >> m >> v >> e;
){
cout << ) << 0.00;
;
}
; i <= n ; i++)
cin >> room[i][];
; i <= n ; i++)
cin >> room[i][];
; i <= n ; i++)
cin >> gl[i];
memset(route , 0x3f , sizeof(route));
while(e--){
int a , b , c;
cin >> a >> b >> c;
route[a][b] = route[b][a] = min(route[a][b] , c);
}
; k <= v ; k++){
route[k][k] = ;
; i <= v ; i++)
; j <= v ; j++)
route[i][j] = min(route[i][j] , route[i][k] + route[k][j]);
}
double minN = 0x7fffffff;
memset(minQW , 0x7f , sizeof(minQW));
minQW[][] = minQW[][] = ;
; i <= n ; i++){
; j--){
minQW[j][] = min(minQW[j][] + calc(i , , ) , minQW[j][] + calc(i , , ));
if(j)
minQW[j][] = min(minQW[j - ][] + calc(i , , ) , minQW[j - ][] + calc(i , , ));
}
}
; i <= m ; i++)
minN = min(minN , min(minQW[i][] , minQW[i][]));
cout << ) << minN;
;
}
*换教室
//组合数+二维前缀和
#include<bits/stdc++.h>
using namespace std;
][] , all[][];
int main(){
ios::sync_with_stdio();
int t , k;
cin >> t >> k;
; i <= ; i++)
; j <= i ; j++)
{
|| j == i) num[i][j] = ;
][j] + num[i - ][j - ]) % k;
;
}
; i <= ; i++)
; j <= ; j++) all[i][j] += all[i][j - ];
; i <= ; i++)
; j <= ; j++) all[i][j] += all[i - ][j];
while(t--){
int a , b;
cin >> a >> b;
cout << all[a][b] << endl;
}
;
}
组合数问题
//队列优化堆
#include<bits/stdc++.h>
using namespace std;
, inf = << ;
][MAXN] , n , m , u , v , q , t , hd[] , tl[];
inline int top(){
;
; i < ; i++)
if(hd[i] != tl[i] && qq[i][hd[i]] > maxN){
maxN = qq[i][hd[i]];
dir = i;
}
)
hd[dir]++;
return maxN;
}
inline void insert(int dir , int num){
qq[dir][tl[dir]++] = num;
}
inline bool cmp(int a , int b){
return a > b;
}
int main(){
cin >> n >> m >> q >> u >> v >> t;
; i < n ; i++)
cin >> qq[][i];
tl[] = n;
sort(qq[] , qq[] + n , cmp);
; i <= m ; i++){
) * q;
)
cout << k << ' ';
int x = (long long)k * u / v;
insert( , x - i * q);
insert( , k - x - i * q);
}
cout << endl;
;
while(k != -inf){
cnt++;
)
cout << k + m * q << ' ';
k = top();
}
;
}
蚯蚓
//状压DP
#include<bits/stdc++.h>
#define eps 1e-12
using namespace std;
inline int min(int a , int b){return a < b ? a : b;}
] , y[];
<< ] , N , pwx[] , numPWX;
inline void init(){
; i < N ; i++){
;
; j < N ; j++){
if(x[i] >= x[j] - eps && x[i] <= x[j] + eps)
continue;
;
; k <= numPWX && ff ; k++)
<< i) | ( << j))) == (( << i) | ( << j)))
ff = ;
if(!ff)
continue;
double a = (y[i] * x[j] - x[i] * y[j]) / x[i] / x[j] / (x[i] - x[j]);
if(a > -eps)
continue;
double b = (y[i] - a * x[i] * x[i]) / x[i];
<< i) | ( << j);
; k < N ; k++)
if(a * x[k] * x[k] + b * x[k] >= y[k] - eps && a * x[k] * x[k] + b * x[k] <= y[k] + eps)
t |= << k;
pwx[++numPWX] = t;
f = ;
}
if(!f){
;
; j <= numPWX && ff ; j++)
<< i)) == ( << i))
ff = ;
if(ff)
pwx[++numPWX] = << i;
}
}
}
int main(){
int T , m;
for(scanf("%d" , &T) ; T ; T--){
numPWX = ;
minN[] = ;
scanf("%d%d" , &N , &m);
memset(minN , , << N));
minN[] = ;
; i < N ; i++)
scanf("%lf %lf" , x + i , y + i);
init();
; i < ( << N) - ; i++)
if(minN[i] < N)
; j <= numPWX ; j++)
minN[i | pwx[j]] = min(minN[i | pwx[j]] , minN[i] + );
printf( << N) - ]);
}
;
}
*愤怒的小鸟
//树上差分+线段树合并
#include<bits/stdc++.h>
#define mid ((l + r) >> 1)
//This code is written by Itst
using namespace std;
inline int read(){
;
;
char c = getchar();
while(c != EOF && !isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(c != EOF && isdigit(c)){
a = (a << ) + (a << ) + (c ^ ');
c = getchar();
}
return f ? -a : a;
}
;
struct Edge{
int end , upEd;
}Ed[MAXN * ];
struct query{
int from , to , val;
}q1[MAXN] , q2[MAXN];
struct node{
int l , r , val;
}Tree[MAXN * ];
] , root[MAXN] , times[MAXN] , ans[MAXN] , cntNode , N , M , cntEd;
inline void addEd(int a , int b){
Ed[++cntEd].end = b;
Ed[cntEd].upEd = head[a];
head[a] = cntEd;
}
inline void pushup(int now){
Tree[now].val = Tree[Tree[now].l].val + Tree[Tree[now].r].val;
}
void insert(int& now , int l , int r , int tar , int val){
if(!now){
now = ++cntNode;
Tree[now].l = Tree[now].r = Tree[now].val = ;
}
if(l == r){
Tree[now].val += val;
return;
}
if(mid >= tar)
insert(Tree[now].l , l , mid , tar , val);
else
insert(Tree[now].r , mid + , r , tar , val);
pushup(now);
}
int query(int now , int l , int r , int tar){
if(!Tree[now].val)
;
if(l == r)
return Tree[now].val;
if(mid >= tar)
return query(Tree[now].l , l , mid , tar);
, r , tar);
}
int merge(int p , int q){
if(!p)
return q;
if(!q)
return p;
Tree[p].val += Tree[q].val;
Tree[p].l = merge(Tree[p].l , Tree[q].l);
Tree[p].r = merge(Tree[p].r , Tree[q].r);
return p;
}
void dfs(int now , int fa){
dep[now] = dep[fa] + ;
jump[now][] = fa;
; i < ; i++)
jump[now][i] = jump[jump[now][i - ]][i - ];
for(int i = head[now] ; i ; i = Ed[i].upEd)
if(Ed[i].end != fa)
dfs(Ed[i].end , now);
}
int jumpToLCA(int x , int y){
if(dep[x] < dep[y])
swap(x , y);
; i >= ; i--)
<< i) >= dep[y])
x = jump[x][i];
if(x == y)
return x;
; i >= ; i--)
if(jump[x][i] != jump[y][i]){
x = jump[x][i];
y = jump[y][i];
}
];
}
int jumpToCH(int x , int y){
; i >= ; i--)
if(jump[x][i] != y)
x = jump[x][i];
return x;
}
void Dfs(int now){
for(int i = head[now] ; i ; i = Ed[i].upEd)
]){
Dfs(Ed[i].end);
root[now] = merge(root[now] , root[Ed[i].end]);
}
ans[now] += query(root[now] , , N << , times[now] + dep[now]);
}
void DFS(int now){
for(int i = head[now] ; i ; i = Ed[i].upEd)
]){
DFS(Ed[i].end);
root[now] = merge(root[now] , root[Ed[i].end]);
}
ans[now] += query(root[now] , -N , N , times[now] - dep[now]);
}
int main(){
#ifdef OJ
freopen("1600.in" , "r" , stdin);
//freopen("1600.out" , "w" , stdout);
#endif
N = read();
M = read();
; i < N ; i++){
int a = read() , b = read();
addEd(a , b);
addEd(b , a);
}
; i <= N ; i++)
times[i] = read();
dfs( , );
; i <= M ; i++){
int a = read() , b = read() , t = jumpToLCA(a , b);
q1[i].from = a;
q1[i].to = t;
q1[i].val = dep[a];
q2[i].from = b;
q2[i].to = jump[t][];
q2[i].val = dep[a] - (dep[t] << );
}
; i <= M ; i++){
insert(root[q1[i]. , N << , q1[i].val , );
insert(root[q1[i].to] , , N << , q1[i].val , -);
}
Dfs();
cntNode = ;
memset(root , , sizeof(root));
; i <= M ; i++){
insert(root[q2[i].);
insert(root[q2[i].to] , -N , N , q2[i].val , -);
}
DFS();
; i <= N ; i++)
printf("%d " , ans[i]);
;
}
*天天爱跑步
NOIP2017(clear)
//小学奥数结论题了解一下
#include<bits/stdc++.h>
using namespace std;
int main()
{
unsigned long long a , b;
cin >> a >> b;
cout << a * b - a - b;
;
}
小凯的疑惑
//比较清爽的大模拟
#include<bits/stdc++.h>
//This code is written by Itst
using namespace std;
inline int read(){
;
;
char c = getchar();
while(c != EOF && !isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(c != EOF && isdigit(c)){
a = (a << ) + (a << ) + (c ^ ');
c = getchar();
}
return f ? -a : a;
}
inline bool getF(){
char c = getchar();
while(!isupper(c))
c = getchar();
return c == 'F';
}
];
map < int , string > m;
set < string > h;
bool cmp(string l , string r){
if(r == "n")
;
if(l == "n" && r != "n")
;
if(l.size() != r.size())
return l.size() > r.size();
; i < l.size() ; i++)
if(l[i] != r[i])
return l[i] > r[i];
;
}
int main(){
#ifdef LG
freopen("3952.in" , "r" , stdin);
//freopen("3952.out" , "w" , stdout);
#endif
for(int T = read() ; T ; --T){
h.clear();
, maxN = , top = , now = ;
;
char c = getchar();
')
c = getchar();
if(c == 'n')
pw = read();
; i <= L ; i++)
if(getF()){
string s , l , r;
cin >> s >> l >> r;
if(h.count(s))
ifERR = ;
else{
h.insert(s);
m[top + ] = s;
if(cmp(l , r))
st[++top] = -;
else
if(r == "n" && l != "n")
st[++top] = ;
else
st[++top] = ;
now += st[top];
maxN = max(maxN , now);
}
}
else
if(!top)
ifERR = ;
else{
now -= st[top];
h.erase(m.find(top--)->second);
}
if(top || ifERR)
puts("ERR");
else
puts(pw == maxN ? "Yes" : "No");
}
;
}
时间复杂度
//最短路+记搜
#include<bits/stdc++.h>
#define int long long
#define MAXN 100010
using namespace std;
inline int read(){
;
;
char c = getchar();
while(!isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(isdigit(c)){
a = (a << ) + (a << ) + (c ^ ');
c = getchar();
}
return f ? -a : a;
}
struct Edge{
int end , upEd , w;
}Ed[MAXN << ] , fanEd[MAXN << ];
] , minDis[MAXN] , fanHead[MAXN] , head[MAXN] , N , K , cntEd , cntFanEd , P;
priority_queue < pair < int , int > > q;
];
inline void addEd(int a , int b , int c){
Ed[++cntEd].end = b;
Ed[cntEd].upEd = head[a];
Ed[cntEd].w = c;
head[a] = cntEd;
}
inline void addFanEd(int a , int b , int c){
fanEd[++cntFanEd].end = b;
fanEd[cntFanEd].upEd = fanHead[a];
fanEd[cntFanEd].w = c;
fanHead[a] = cntFanEd;
}
int dfs(int now , int sub){
if(sub > K)
;
if(vis[now][sub])
;
)
return ans[now][sub];
ans[now][sub] = ;
vis[now][sub] = ;
for(int i = head[now] ; i ; i = Ed[i].upEd){
int t = dfs(Ed[i].end , minDis[Ed[i].end] + Ed[i].w - minDis[now] + sub);
)
;
else
ans[now][sub] = (ans[now][sub] + t) % P;
}
vis[now][sub] = ;
if(now == N)
ans[now][sub]++;
return ans[now][sub];
}
void Dijk(){
memset(minDis , 0x3f , sizeof(minDis));
minDis[N] = ;
q.push(make_pair( , N));
while(!q.empty()){
pair < int , int > t = q.top();
q.pop();
if(-t.first > minDis[t.second])
continue;
for(int i = fanHead[t.second] ; i ; i = fanEd[i].upEd)
if(minDis[fanEd[i].end] > minDis[t.second] + fanEd[i].w){
minDis[fanEd[i].end] = minDis[t.second] + fanEd[i].w;
q.push(make_pair(-minDis[fanEd[i].end] , fanEd[i].end));
}
}
}
main(){
for(int T = read() ; T ; T--){
N = read();
int M = read();
K = read();
P = read();
memset(fanHead , , sizeof(fanHead));
memset(head , , sizeof(head));
memset(ans , - , sizeof(ans));
memset(vis , , sizeof(vis));
cntEd = cntFanEd = ;
while(M--){
int a = read() , b = read() , c = read();
addEd(a , b , c);
addFanEd(b , a , c);
}
Dijk();
cout << dfs( , ) << endl;
}
;
}
*逛公园
//记忆化搜索
#include<bits/stdc++.h>
#define MAXN 1001
#define dou double
using namespace std;
] , v[MAXN] , T;
dou mm[MAXN][MAXN];
dou dis(dou x1 , dou x2 , dou y1 , dou y2 , dou z1 , dou z2)
{
return sqrt((x1 - x2) * (x1 - x2) +(y1 - y2) * (y1 - y2) +(z1 - z2) * (z1 - z2));
}
bool sr(int m)
{
v[m] = ;
;
] + r >= h) o = ;
; i <= n && !o ; i++)
if(i != m && !v[i])
{
if(!mm[i][m])
mm[m][i] = dis(p[i][] , p[m][] , p[i][] , p[m][] , p[i][] , p[m][]);
else continue;
* r) o = sr(i);
}
return o;
}
int main()
{
ios::sync_with_stdio(false);
;
for(cin >> T ; T ; T--)
{
cin >> n >> h >> r;
; i <= n ; i++)
{
cin >> p[i][] >> p[i][] >> p[i][];
v[i] = ;
; j <= n ; j++) mm[i][j] = ;
}
;
; i <= n && !o ; i++) ] - r <= ) o = sr(i);
cout << (b ? "\n" : "") << (o ? "Yes" : "No");
b = ;
}
;
}
奶酪
//拆点Splay->动态开点线段树
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
;
char c = getchar();
while(!isdigit(c))
c = getchar();
while(isdigit(c)){
a = (a << ) + (a << ) + (c ^ ');
c = getchar();
}
return a;
}
;
struct node{
];
}Tree[];
] , rootBef[MAXN + ] , rootBeh[MAXN + ];
inline int create(int l , int r , bool f){
int t = ++cntNode;
Tree[t].l = l;
Tree[t].r = r;
if(f)
Tree[t].size = r - l + ;
return t;
}
inline void split(int now , bool f){
Tree[now].ch[] = create(Tree[now].l , Tree[now].r + Tree[now].l >> , f);
Tree[now].ch[] = create(Tree[now].l + Tree[now].r + >> , Tree[now].r , f);
}
int findKth(int now , int k , bool f){
Tree[now].size--;
if(Tree[now].l == Tree[now].r)
return f ? Tree[now].val : Tree[now].l;
] && !Tree[now].ch[])
split(now , );
]].size < k)
] , k - Tree[Tree[now].ch[]].size , f);
] , k , f);
}
void insert(int now , int tar , int k){
Tree[now].size++;
if(Tree[now].l == Tree[now].r){
Tree[now].val = k;
return;
}
])
split(now , );
]].r)
insert(Tree[now].ch[] , tar , k);
else
insert(Tree[now].ch[] , tar , k);
}
signed main(){
N = read();
M = read();
Q = read();
; i <= N ; i++){
rootBef[i] = create( , M - , );
rootBeh[i] = create( , Q , );
}
rootBef[N + ] = create( , N , );
rootBeh[N + ] = create( , Q , );
; i <= N ; i++)
insert(rootBef[N + ] , i , i * M);
; i <= Q ; i++){
int a = read() , b = read() , t;
if(b == M)
t = Tree[rootBef[N + ]].size >= a ? findKth(rootBef[N + ] , a , ) : findKth(rootBeh[N + ] , a - Tree[rootBef[N + ]].size , );
else{
t = Tree[rootBef[a]].size >= b ? findKth(rootBef[a] , b , ) + (a - ) * M : findKth(rootBeh[a] , b - Tree[rootBef[a]].size , );
insert(rootBeh[a] , ++cnt[a] , Tree[rootBef[N + ]].size >= a ? findKth(rootBef[N + ] , a , ) : findKth(rootBeh[N + ] , a - Tree[rootBef[N + ]].size , ));
}
printf("%lld\n" , t);
insert(rootBeh[N + ] , i , t);
}
;
}
*列队
NOIP2002-2017提高组题解的更多相关文章
- noip2010提高组题解
NOIP2010提高组题解 T1:机器翻译 题目大意:顺序输入n个数,有一个队列容量为m,遇到未出现元素入队,求入队次数. AC做法:直接开1000的队列模拟过程. T2:乌龟棋 题目大意:有长度为n ...
- NOIP 2014 提高组 题解
NOIP 2014 提高组 题解 No 1. 生活大爆炸版石头剪刀布 http://www.luogu.org/problem/show?pid=1328 这是道大水题,我都在想怎么会有人错了,没算法 ...
- NOIP 2001 提高组 题解
NOIP 2001 提高组 题解 No 1. 一元三次方程求解 https://vijos.org/p/1116 看见有人认真推导了求解公式,然后猥琐暴力过的同学们在一边偷笑~~~ 数据小 暴力枚举即 ...
- NOIP 2000 提高组 题解
NOIP2000 提高组 题解 No 1. 进制转换 https://www.rqnoj.cn/problem/295 水题 对于n和基数r, 每次用n mod r, 把余数按照逆序排列 注意 mod ...
- 【NOIP2018】提高组题解
[NOIP2018]提高组题解 其实就是把写过的打个包而已 道路铺设 货币系统 赛道修建 旅行 咕咕咕 咕咕咕
- NOIP 2017 提高组 day1t2 时间复杂度
P3952 时间复杂度 标签 NOIp提高组 2017 时空限制 1000ms / 128MB 小明正在学习一种新的编程语言 A++,刚学会循环语句的他激动地写了好多程序并 给出了他自己算出的时间复杂 ...
- noip2002提高组题解
再次280滚粗.今天早上有点事情,所以做题的时候一直心不在焉,应该是三天以来状态最差的一次,所以这个分数也还算满意了.状态真的太重要了. 第一题:均分纸牌 贪心.(昨天看BYVoid的noip2001 ...
- noip2009提高组题解
NOIP2009题解 T1:潜伏者 题目大意:给出一段密文和破译后的明文,一个字母对应一个密文字母,要求破译一段密文,如果有矛盾或有未出现密文无法破译输出failed,否则输出明文. 思路:纯模拟题 ...
- noip2008提高组题解
第一题:笨小猴 模拟 第二题:火柴棒等式 搜索 深搜不用说,确定出两个加数然后判断能否拼出等式. 枚举确实不太好搞,因为枚举范围不确定,太大了容易超时,太小了容易漏解.不过这题的数据貌似很温和,我 ...
- noip2007提高组题解
题外话:这一年的noip应该是最受大众关心的,以至于在百度上输入noip第三个关键字就是noip2007.主要是由于这篇文章:http://www.zhihu.com/question/2110727 ...
随机推荐
- 前端开发面试题-HTML(转载)
本文由 本文的原作者markyun 收集总结了一些前端面试题,初学者阅后也要用心钻研其中的原理,重要知识需要系统学习.透彻学习,形成自己的知识链.万不可投机取巧,临时抱佛脚只求面试侥幸混过关是错误的! ...
- Sharepoint 2013 Gatherer 数据库的架构版本低于此 Gatherer 应用程序支持的向后兼容的最低架构版本
管理中心 ->升级和迁移 ->查看数据库状态 解决方法: 开始-运行(以管理员身份运行),输入如下命令. cd C:\Program Files\Common Files\Microso ...
- 惊闻企业Web应用生成平台 活字格 V4.0 免费了,不单可视化设计器免费,服务器也免费!
官网消息: 针对活字格开发者,新版本完全免费!您可下载活字格 Web 应用生成平台 V4.0 Updated 1,方便的创建各类 Web 应用系统,任意部署,永不过期. 我之前学习过活字格,也曾经向用 ...
- html5手机移动端三级联动城市选择器
//我的地址 var area1 = new LArea(); area1.init({ 'trigger': '#demo1', //触发选择控件的文本框,同时选择完毕后name属性输出到该位置 ' ...
- c#权限验证
在开发过程中,需要对访问者的身份做权限验证(再filter中进行权限过滤). 在每次进入控制器方法之前进行调用:如 [ControllerAuth] [RoutePrefix("Clinic ...
- 第三章 Hyper-V 2012 R2配置选项
原书中的第二章 是介绍了下hyper-v的管理器和检查点的使用,导入导出虚拟机,所以我跳过了不高兴写,很简单.直接进入第三部分,介绍虚拟机的三个重要组成部分:CPU,内存,硬盘的配置选项. Hyper ...
- yum-config-manager命令找不到
安装: 命令在yum-utils 包里,安装既可以解决:yum -y install yum-utils 当然你也可以通过 dnf 替代 dnf 命令替代: 禁用仓库命令就是: dnf config- ...
- openSUSE搭建OpenVPN
目录 openSUSE搭建OpenVPN 环境 安装openVPN服务端 安装easy-rsa工具 配置vars文件 创建服务端证书及key 创建客户端证书 疏理证书文件 服务端配置 启动openvp ...
- Alpha冲刺!Day13 - 小结
Alpha冲刺!Day13 - 小结 各个成员今日完成的任务 今天团队极限编程12小时,从早上九点要求每个人给出一张电脑全屏截图以示开始干活,每两小时汇报进度确认已经做了什么.现在在做什么. 各节点列 ...
- JDBC学习笔记之SQLException介绍
1. SQLException 的概述 当使用 JDBC 与数据源(在本文中的数据源表示我们实际使用的数据库)进行交互的时候遇见错误的时候,将会抛出名为 SQLException 的异常.一个 SQL ...