0%

思路讲解

就是这么说那,还是不要省一些东西,lson简写成 l 容易导致误解使自己写错

然后三分可以这么写

1
2
3
4
5
6
7
8
m1=l+(r-l)/3;
m2=l+2*(r-l)/3;
tr[++tot].st=l,tr[tot].ed=m1;
tr[x].l=tot;
tr[++tot].st=m1+1,tr[tot].ed=m2;
tr[x].m=tot;
tr[++tot].st=m2+1,tr[tot].ed=r;
tr[x].r=tot;

AC代码

AC

https://atcoder.jp/contests/abc391/submissions/62327989

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <bits/stdc++.h>
#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define ROF(i, a, b) for (int i = a; i >= b; --i)
#define all(x) x.begin(),x.end()

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
typedef array<ll,3> arr;
typedef pair<ll,bool> plb;
typedef double DB;
const ll MAXN=static_cast<ll>(2e6)+10,MAXval=static_cast<ll>(1e18)+3;

ll N;
ll pow3[18];
// vector<ll> needChange[2][15];
bool stand;
bool A[MAXN]; // 经过修改的字符串(N即是未修改)
ll tot;

struct Tree{
ll l,m,r;
// bool val;
ll st,ed;
}tr[MAXN*4];

inline plb buildTree(ll x){
if(tr[x].st==tr[x].ed) {
// cout<<tr[x].st<<' '<<tr[x].ed<<'\n';
return {1,A[tr[x].st]};
}
ll l=tr[x].st,r=tr[x].ed;
ll m1,m2;
m1=l+(r-l)/3;
m2=l+2*(r-l)/3;
tr[++tot].st=l,tr[tot].ed=m1;
tr[x].l=tot;
tr[++tot].st=m1+1,tr[tot].ed=m2;
tr[x].m=tot;
tr[++tot].st=m2+1,tr[tot].ed=r;
tr[x].r=tot;
// needChange 如果要改动需要改动多少
vector<ll> needCh[2];
// cout<<tr[x].st<<' '<<tr[x].ed<<'\n';
plb rec1=buildTree(tr[x].l);
needCh[rec1.second].push_back(rec1.first);
plb rec2=buildTree(tr[x].m);
needCh[rec2.second].push_back(rec2.first);
plb rec3=buildTree(tr[x].r);
needCh[rec3.second].push_back(rec3.first);
if(needCh[0].size()>needCh[1].size()){
if(needCh[0].size()-needCh[1].size()==1){
return {min(needCh[0][0],needCh[0][1]),false};
}else{
sort(all(needCh[0]));
return {needCh[0][0]+needCh[0][1],false};
}
}else{
if(needCh[1].size()-needCh[0].size()==1){
// 改动该点值的代价 该点的值
return {min(needCh[1][0],needCh[1][1]),true};
}else{
sort(all(needCh[1]));
return {needCh[1][0]+needCh[1][1],true};
}
}
}


int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>N;
pow3[0]=1;
FOR(i, 1, 15){
pow3[i]=pow3[i-1]*3;
}
FOR(i, 1, pow3[N]){
char a;
cin>>a;
if(a=='1') A[i]=true;
else A[i]=false;
}

tr[++tot].st=1,tr[tot].ed=pow3[N];
plb rec=buildTree(tot);
cout<<rec.first<<'\n';
// cout<<A[0][1]<<'\n';
return 0;
}

/*
AC
https://atcoder.jp/contests/abc391/submissions/62327989
*/

心路历程(WA,TLE,MLE……)

思路讲解

https://www.luogu.com.cn/discuss/1021064

没什么其他要注意的,就是注意long double才能保证在long long范围内不被卡精度

1
maze[x][y]*1.0l <ans*1.0l/X

AC代码

https://atcoder.jp/contests/abc384/submissions/62254421

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <bits/stdc++.h>
#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define ROF(i, a, b) for (int i = a; i >= b; --i)
#define all(x,size) x.begin()+1,x.begin()+size+1
#define all1(x) x.begin(),x.end()

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
typedef array<ll,3> arr;
typedef double DB;
const ll MAXN=510,MAXval=static_cast<ll>(1e18)+3;

ll N,M,X,sx,sy;
ll maze[MAXN][MAXN];
bool vis[MAXN][MAXN];
struct cmp{
bool operator()(pll a,pll b){
return maze[a.first][a.second]>maze[b.first][b.second];
}
};
ll dx[4]={1,0,-1,0};
ll dy[4]={0,1,0,-1};

int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>N>>M>>X>>sx>>sy;
FOR(i, 1, N){
FOR(j, 1, M){
cin>>maze[i][j];
}
}
priority_queue<pll,vector<pll>,cmp> pq;
pq.push({sx,sy});
vis[sx][sy]=true;
ll ans=0;
// cout<<"Yes\n";
while (!pq.empty()) {
ll x=pq.top().first,y=pq.top().second;
pq.pop();
if(maze[x][y]*1.0l <ans*1.0l/X || (x==sx && y==sy)){
ans+=maze[x][y];
// cout<<ans<< ' '<< x <<' '<< y <<'\n';
FOR(i, 0, 3){
ll fx=x+dx[i],fy=y+dy[i];
if(fx<1 || fx>N) continue;
if(fy<1 || fy>M) continue;
if(vis[fx][fy]) continue;
vis[fx][fy]=true;
pq.push({fx,fy});
}
}
}
cout<<ans<<'\n';
return 0;
}
/*
3 3 2
2 2
14 6 9
4 9 20
17 15 7

*/

心路历程(WA,TLE,MLE……)

思路讲解

图比较简陋,大概就是叙述了为什么可以用双指针,以及问题的转化

我就想多加一段中可不可以?当然可以

多加一段前或后 前&后?也可以

我想全部用双指针嘛,所以说选前后相当于就是把中间扣掉嘛

AC代码

https://atcoder.jp/contests/abc384/submissions/62236712

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <bits/stdc++.h>
#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define ROF(i, a, b) for (int i = a; i >= b; --i)
#define all(x,size) x.begin()+1,x.begin()+size+1
#define all1(x) x.begin(),x.end()

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
typedef array<ll,3> arr;
typedef double DB;
const ll MAXN=static_cast<ll>(2e5)+10,MAXval=static_cast<ll>(1e18)+3;

ll N,S,A[MAXN],sumA[MAXN],sumBack[MAXN],originS;

int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>N>>originS;
// ll sumAll=0;
FOR(i, 1, N){
cin>>A[i];
sumA[i]=sumA[i-1]+A[i];
}
ROF(i, N, 1){
sumBack[i]=sumBack[i+1]+A[i];
}
S=originS;
if(originS%sumA[N]==0) {cout<<"Yes\n";return 0;}
if(S>sumA[N]){ // 大于sumA的问题转化为小于sumA的问题
S=originS%sumA[N];
// 双指针
ll flag=2;
FOR(i, 1, N){
ll sum=sumA[flag-1]-sumA[i-1];
bool needBreak=false;
FOR(j, flag, N){
if(sum>S) {flag=j;break;}
if(sum+A[j]<S && j==N) {needBreak=true;break;}
if(sum==S){
cout<<"Yes\n";
return 0;
}
sum+=A[j];
}
if(needBreak) break;
}
flag=2;
FOR(i, 1, N){
ll sum=sumA[flag-1]-sumA[i-1];
bool needBreak=false;
FOR(j, flag, N){
if(sum>sumA[N]-S) {flag=j;break;}
if(sum+A[j]<sumA[N]-S && j==N) {needBreak=true;break;}
if(sum==sumA[N]-S){
cout<<"Yes\n";
return 0;
}
sum+=A[j];
}
if(needBreak) break;
}
}else{
ll flag=2;
FOR(i, 1, N){
ll sum=sumA[flag-1]-sumA[i-1];
FOR(j, flag, N){
if(sum>S) {flag=j;break;}
if(sum==S){
cout<<"Yes\n";
return 0;
}
sum+=A[j];
}
}
}
cout<<"No\n";
return 0;
}
/*
WA*2
https://atcoder.jp/contests/abc384/submissions/62236467

3 15
3 8 4

*/

心路历程(WA,TLE,MLE……)

WA*2
https://atcoder.jp/contests/abc384/submissions/62236467

感谢这个讨论

https://www.luogu.com.cn/discuss/1022682

1
2
3
3 15
3 8 4

其实我之前写过一个这种情况的特判,被我自己删掉了

思路讲解

总体上来说这题还是比较顺的,就是顺着做就好了,也没用什么算法,for循环就完了

1
2
3
4
sort(all1(sons),greater<ll>());
FOR(j, 0, sons.size()-1){
remainNode=max(remainNode,1+sons[j]*(j+1)+j+1);
}

核心是这一段代码,因为是0-based,所以要 j+1

AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <bits/stdc++.h>
#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define ROF(i, a, b) for (int i = a; i >= b; --i)
#define all(x,size) x.begin()+1,x.begin()+size+1
#define all1(x) x.begin(),x.end()

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
typedef array<ll,3> arr;
typedef double DB;
const ll MAXN=static_cast<ll>(3e5)+10,MAXval=static_cast<ll>(1e18)+3;

ll N,T;
vector<ll> G[MAXN];

int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>N;
FOR(i, 1, N-1){
ll u,v;
cin>>u>>v;
G[u].push_back(v);
G[v].push_back(u);
}
ll ans=MAXval;
FOR(i, 1, N){
ll remainNode=0;
vector<ll> sons; // 他的子节点的子节点有几个?
FOR(j, 0, G[i].size()-1){
ll node=G[i][j];
sons.push_back(G[node].size()-1);
}
sort(all1(sons),greater<ll>());
FOR(j, 0, sons.size()-1){
remainNode=max(remainNode,1+sons[j]*(j+1)+j+1);
}
ans=min(ans,N-remainNode);

// cout<<"debug:\n";
// FOR(j, 0, sons.size()-1){
// cout<<sons[j]<<' ';
// }
// cout<<'\n';
}
cout<<ans<<'\n';
return 0;
}
/*
AC
https://atcoder.jp/contests/abc385/submissions/62235314
*/

心路历程(WA,TLE,MLE……)

思路讲解

主要就是一个stl的使用,思路就是查到了直接删而不是查到了加进一个东西里

AC代码

https://atcoder.jp/contests/abc385/tasks/abc385_d

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <bits/stdc++.h>
#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define ROF(i, a, b) for (int i = a; i >= b; --i)
#define SZ(x) ((int)x.size())
#define all(x,size) x.begin()+1,x.begin()+size+1
#define all1(x) x.begin(),x.end()

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
typedef array<ll,3> arr;
typedef double DB;
const ll MAXN=static_cast<ll>(2e5)+10,MAXval=static_cast<ll>(1e18)+3;

ll N,T;
pll xy[MAXN];
struct cmpx{
bool operator()(pll a,pll b) const{
if(a.first!=b.first) return a.first<b.first;
return a.second<b.second;
}
};
struct cmpy{
bool operator()(pll a,pll b) const{
if(a.second!=b.second) return a.second<b.second;
return a.first<b.first;
}
};
set<pll,cmpx> stx;
set<pll,cmpy> sty;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
ll sx,sy;
cin>>N>>T>>sx>>sy;
FOR(i, 1, N){
cin>>xy[i].first>>xy[i].second;
stx.insert(xy[i]);
sty.insert(xy[i]);
}
FOR(i, 1, T){
char op;ll dis;
cin>>op>>dis;
// cout<<"Yes "<<i<<'\n';
if(op=='U'){
set<pll,cmpx>::iterator it=stx.lower_bound({sx,sy});
while(it!=stx.end() && it->first== sx && it->second<=sy+dis){
set<pll,cmpx>::iterator next_it=next(it);
sty.erase({it->first,it->second});
stx.erase(it);
it=next_it;
}
sy+=dis;
}else if(op=='D'){
set<pll,cmpx>::iterator it=stx.lower_bound({sx,sy});
if(it==stx.begin() || stx.empty()){
sy-=dis;
continue;
}
it--;
while(it!=stx.end() && it->first== sx && it->second>=sy-dis){
if(it==stx.begin()){
sty.erase({it->first,it->second});
stx.erase(it);
break;
}
set<pll,cmpx>::iterator prev_it=prev(it);
sty.erase({it->first,it->second});
stx.erase(it);
it=prev_it;
}
sy-=dis;
}else if(op=='R'){
set<pll,cmpy>::iterator it=sty.lower_bound({sx,sy});
while(it!=sty.end() && it->first<=sx+dis && it->second==sy){
set<pll,cmpy>::iterator next_it=next(it);
stx.erase({it->first,it->second});
sty.erase(it);
it=next_it;
}
sx+=dis;
}else {
set<pll,cmpy>::iterator it=sty.lower_bound({sx,sy});
if(it==sty.begin() || sty.empty()){
sx-=dis;
continue;
}
it--;
while(it!=sty.end() && it->first>=sx-dis && it->second==sy){
if(it==sty.begin()){
stx.erase({it->first,it->second});
sty.erase(it);
break;
}
set<pll,cmpy>::iterator prev_it=prev(it);
stx.erase({it->first,it->second});
sty.erase(it);
it=prev_it;
}
sx-=dis;
}
}
cout<<sx<<' '<<sy<<' '<<N-stx.size()<<'\n';
return 0;
}
/*
AC
https://atcoder.jp/contests/abc385/submissions/62232268
*/

心路历程(WA,TLE,MLE……)

https://atcoder.jp/contests/abc385/submissions/62232078

RE

总的来说就是要防御性编程,能先判断的不要后判断(像我是后判断的,这不好,有些情况会RE)

然后空什么的特殊情况一定也要判断,不要嫌麻烦。

image