不算太难,大概就是个找性质然后 BIT 维护一下就行,比较弱所以写了四五十分钟,拍完之后大概一个点吧,不过也算切了。
xxxxxxxxxx
831
2
3
4
5
6
7
8
9
10
11using namespace std;
12// using namespace __gnu_pbds;
13
14mt19937 rnd(random_device{}());
15int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
16bool rnddd(int x){return rndd(1, 100) <= x;}
17
18typedef unsigned int uint;
19typedef unsigned long long unll;
20typedef long long ll;
21typedef long double ld;
22
23
24
25template< typename T = int >
26inline T read(void);
27
28int lim;
29int N;
30int a[110000];
31int ra[110000];
32bool exist[110000];
33ll ans(0);
34vector < int > data;
35vector < int > tmp;
36
37class BIT{
38private:
39 ll tr[210000];
40public:
41 int lowbit(int x){return x & -x;}
42 void Modify(int x, ll v){while(x <= lim)tr[x] = (tr[x] + v) % MOD, x += lowbit(x);}
43 ll Query(int x){ll ret(0); while(x)ret = (ret + tr[x]) % MOD, x -= lowbit(x); return ret;}
44 ll QueryPoint(int x){return (Query(x) - Query(x - 1) + MOD) % MOD;}
45 ll QueryReal(int x){ll tmp = QueryPoint(x); return (Query(x - 1) - (tmp ? tmp - 1 : 0) + MOD) % MOD;}
46}bit;
47
48int main(){
49 freopen("subseries.in", "r", stdin);
50 freopen("subseries.out", "w", stdout);
51 lim = N = read();
52 for(int i = 1; i <= N; ++i)a[i] = read(), data.emplace_back(a[i]);
53 sort(data.begin(), data.end());
54 for(int i = 1; i <= N; ++i)a[i] = distance(data.begin(), lower_bound(data.begin(), data.end(), a[i]) + 1);
55 // for(int i = N; i <= 1; ++i)if(!exist[a[i]])exist[a[i]] = true, tmp.emplace_back(a[i]);
56 // for(auto it = tmp.rbegin(); it != tmp.rend(); ++it)ra[++lim] = *it;
57 for(int i = 1; i <= N; ++i){
58 ll ret = bit.QueryReal(a[i]);
59 // for(int j = 1; j <= N; ++j)
60 // printf("Query range : %d = %lld, point : %d = %lld\n", j, bit.Query(j), j, bit.QueryPoint(j));
61 // printf("point: %lld, ret = %lld\n", bit.QueryPoint(a[i]), ret);
62 bit.Modify(a[i], ret + (bit.QueryPoint(a[i]) ? 0 : 1));
63 ans = (ans + ret) % MOD;
64 }printf("%lld\n", ans);
65 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
66 return 0;
67}
68
69template < typename T >
70inline T read(void){
71 T ret(0);
72 short flag(1);
73 char c = getchar();
74 while(c != '-' && !isdigit(c))c = getchar();
75 if(c == '-')flag = -1, c = getchar();
76 while(isdigit(c)){
77 ret *= 10;
78 ret += int(c - '0');
79 c = getchar();
80 }
81 ret *= flag;
82 return ret;
83}
原题 51nod-1326 遥远的旅途。
同余最短路,又是新的知识点,很奇怪也很阴间,第一眼还以为这玩意是 exgcd,然后发现好像是 exexexexexexexgcd。。。
写了个骗分然后一分没有。。
奇怪的博弈,没找到性质,寄。
原题 CF609E Minimum spanning tree for each edge。
本来已经基本切了。。MST + 树剖,赛时想到了也写了,然后对拍发现边权转点权的时候没忽略 LCA,然后改完感觉问题不大了。。最后发现又犯了个经典 nt 错误。。直接
xxxxxxxxxx
1821
2
3
4
5
6
7
8
9
10
11using namespace std;
12// using namespace __gnu_pbds;
13
14mt19937 rnd(random_device{}());
15int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
16bool rnddd(int x){return rndd(1, 100) <= x;}
17
18typedef unsigned int uint;
19typedef unsigned long long unll;
20typedef long long ll;
21typedef long double ld;
22
23
24
25template< typename T = int >
26inline T read(void);
27
28struct Edge{
29 Edge* nxt;
30 int to;
31 ll val;
32 OPNEW;
33}ed[410000];
34ROPNEW(ed);
35Edge* head[MAXNM];
36ll val[210000];
37
38class UnionFind{
39private:
40 int fa[MAXNM];
41public:
42 UnionFind(void){for(int i = 1; i <= 201000; ++i)fa[i] = i;}
43 int Find(int x){return fa[x] == x ? x : fa[x] = Find(fa[x]);}
44 void Union(int origin, int son){fa[Find(son)] = Find(origin);}
45}uf;
46
47int N, M;
48bool intree[MAXNM];
49ll ans[MAXNM];
50ll origin(0);
51struct Edges{
52 int val;
53 int s, t;
54 int idx;
55 friend const bool operator < (const Edges &a, const Edges &b){return a.val < b.val;}
56};
57vector < Edges > edges;
58tuple < int, int, int > qs[210000];
59
60int dfn[MAXNM], fa[MAXNM], hson[MAXNM], siz[MAXNM], dep[MAXNM], top[MAXNM], idx[MAXNM];
61
62void dfs_edge_to_vertex(int p = 1, int ffa = 0){
63 for(auto i = head[p]; i; i = i->nxt)
64 if(SON != ffa)val[SON] = i->val, dfs_edge_to_vertex(SON, p);
65}
66
67void dfs_pre(int p = 1, int ffa = 0){
68 // printf("pre : %d\n", p);
69 fa[p] = ffa;
70 siz[p] = 1;
71 dep[p] = dep[ffa] + 1;
72 for(auto i = head[p]; i; i = i->nxt){
73 if(SON == ffa)continue;
74 dfs_pre(SON, p);
75 siz[p] += siz[SON];
76 if(!hson[p] || siz[SON] > siz[hson[p]])hson[p] = SON;
77 }
78}
79void dfs(int p = 1, int tp = 1){
80 // printf("dfs: %d, %d\n", p, tp);
81 static int curdfn(0);
82 dfn[p] = ++curdfn;
83 idx[curdfn] = p;
84 top[p] = tp;
85 if(hson[p])dfs(hson[p], tp);
86 for(auto i = head[p]; i; i = i->nxt)
87 if(SON != fa[p] && SON != hson[p])dfs(SON, SON);
88}
89
90class SegTree{
91private:
92 ll tr[MAXNM << 2];
93
94
95
96public:
97 void Pushup(int p){tr[p] = max(tr[LS], tr[RS]);}
98 void Build(int p = 1, int gl = 1, int gr = N){
99 if(gl == gr)return tr[p] = val[idx[gl = gr]], void();
100 Build(LS, gl, MID);
101 Build(RS, MID + 1, gr);
102 Pushup(p);
103 }
104 ll QueryMax(int l, int r, int p = 1, int gl = 1, int gr = N){
105 // if(l > r || !l || !r)return -1;
106 // printf("Querying l = %d, t = %d, p = %d, gl = %d, gr = %d\n", l, r, p, gl, gr);
107 if(l <= gl && gr <= r)return tr[p];
108 return max(
109 l <= MID ? QueryMax(l, r, LS, gl, MID) : -1,
110 MID + 1 <= r ? QueryMax(l, r, RS, MID + 1, gr) : -1
111 );
112 }
113}st;
114
115ll QueryMax(int s, int t){
116 ll ret(0);
117 while(top[s] != top[t]){
118 if(dep[s] < dep[t])swap(s, t);
119 ret = max(ret, st.QueryMax(dfn[top[s]], dfn[s]));
120 // printf("s = %d, t = %d, tps = %d, dfntp = %d, dfn = %d Max:%lld\n", s, t, top[s], dfn[top[s]], dfn[s], st.QueryMax(dfn[top[s]], dfn[s]));
121 s = fa[top[s]];
122 }if(dep[s] < dep[t])swap(s, t);
123 return max(ret, st.QueryMax(dfn[hson[t]], dfn[s]));
124}
125
126int main(){
127 freopen("tree.in", "r", stdin);
128 freopen("tree.out", "w", stdout);
129 N = read(), M = read();
130 for(int i = 1; i <= M; ++i){
131 int s = read(), t = read(), v = read();
132 edges.emplace_back(Edges{v, s, t, i});
133 qs[i] = {s, t, v};
134 }sort(edges.begin(), edges.end());
135 for(auto e : edges)
136 if(uf.Find(e.s) != uf.Find(e.t))
137 uf.Union(e.s, e.t),
138 head[e.s] = new Edge{head[e.s], e.t, e.val},
139 head[e.t] = new Edge{head[e.t], e.s, e.val},
140 intree[e.idx] = true,
141 origin += e.val;
142 dfs_edge_to_vertex();
143 dfs_pre();
144 dfs();dfn[0] = 1;
145 st.Build();
146 // printf("%d\n", st.QueryMax(5, 5));
147 for(int i = 1; i <= M; ++i){
148 if(intree[i]){ans[i] = origin; continue;}
149 int s, t, v; tie(s, t, v) = qs[i];
150 // printf("Edge:%d, %d->%d max = %lld\n", i, s, t, QueryMax(s, t));
151 ans[i] = origin - QueryMax(s, t) + v;
152 }
153 for(int i = 1; i <= M; ++i)printf("%lld\n", ans[i]);
154 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
155 return 0;
156}
157
158template < typename T >
159inline T read(void){
160 T ret(0);
161 short flag(1);
162 char c = getchar();
163 while(c != '-' && !isdigit(c))c = getchar();
164 if(c == '-')flag = -1, c = getchar();
165 while(isdigit(c)){
166 ret *= 10;
167 ret += int(c - '0');
168 c = getchar();
169 }
170 ret *= flag;
171 return ret;
172}
173/*
1745 7
1751 2 3
1761 3 1
1771 4 5
1782 3 2
1792 5 3
1803 4 2
1814 5 4
182*/
咕咕咕
咕咕咕
又是经典的 nt 错误,第一次错的时候印象不够深刻。。然后这次又错了,后来自己手推才发现这个逻辑错误,这回估计忘不了了。。。
xxxxxxxxxx
1821
2
3
4
5
6
7
8
9
10
11using namespace std;
12// using namespace __gnu_pbds;
13
14mt19937 rnd(random_device{}());
15int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
16bool rnddd(int x){return rndd(1, 100) <= x;}
17
18typedef unsigned int uint;
19typedef unsigned long long unll;
20typedef long long ll;
21typedef long double ld;
22
23
24
25template< typename T = int >
26inline T read(void);
27
28struct Edge{
29 Edge* nxt;
30 int to;
31 ll val;
32 OPNEW;
33}ed[410000];
34ROPNEW(ed);
35Edge* head[MAXNM];
36ll val[210000];
37
38class UnionFind{
39private:
40 int fa[MAXNM];
41public:
42 UnionFind(void){for(int i = 1; i <= 201000; ++i)fa[i] = i;}
43 int Find(int x){return fa[x] == x ? x : fa[x] = Find(fa[x]);}
44 void Union(int origin, int son){fa[Find(son)] = Find(origin);}
45}uf;
46
47int N, M;
48bool intree[MAXNM];
49ll ans[MAXNM];
50ll origin(0);
51struct Edges{
52 int val;
53 int s, t;
54 int idx;
55 friend const bool operator < (const Edges &a, const Edges &b){return a.val < b.val;}
56};
57vector < Edges > edges;
58tuple < int, int, int > qs[210000];
59
60int dfn[MAXNM], fa[MAXNM], hson[MAXNM], siz[MAXNM], dep[MAXNM], top[MAXNM], idx[MAXNM];
61
62void dfs_edge_to_vertex(int p = 1, int ffa = 0){
63 for(auto i = head[p]; i; i = i->nxt)
64 if(SON != ffa)val[SON] = i->val, dfs_edge_to_vertex(SON, p);
65}
66
67void dfs_pre(int p = 1, int ffa = 0){
68 // printf("pre : %d\n", p);
69 fa[p] = ffa;
70 siz[p] = 1;
71 dep[p] = dep[ffa] + 1;
72 for(auto i = head[p]; i; i = i->nxt){
73 if(SON == ffa)continue;
74 dfs_pre(SON, p);
75 siz[p] += siz[SON];
76 if(!hson[p] || siz[SON] > siz[hson[p]])hson[p] = SON;
77 }
78}
79void dfs(int p = 1, int tp = 1){
80 // printf("dfs: %d, %d\n", p, tp);
81 static int curdfn(0);
82 dfn[p] = ++curdfn;
83 idx[curdfn] = p;
84 top[p] = tp;
85 if(hson[p])dfs(hson[p], tp);
86 for(auto i = head[p]; i; i = i->nxt)
87 if(SON != fa[p] && SON != hson[p])dfs(SON, SON);
88}
89
90class SegTree{
91private:
92 ll tr[MAXNM << 2];
93
94
95
96public:
97 void Pushup(int p){tr[p] = max(tr[LS], tr[RS]);}
98 void Build(int p = 1, int gl = 1, int gr = N){
99 if(gl == gr)return tr[p] = val[idx[gl = gr]], void();
100 Build(LS, gl, MID);
101 Build(RS, MID + 1, gr);
102 Pushup(p);
103 }
104 ll QueryMax(int l, int r, int p = 1, int gl = 1, int gr = N){
105 if(l > r || !l || !r)return -1;
106 // printf("Querying l = %d, t = %d, p = %d, gl = %d, gr = %d\n", l, r, p, gl, gr);
107 if(l <= gl && gr <= r)return tr[p];
108 return max(
109 l <= MID ? QueryMax(l, r, LS, gl, MID) : -1,
110 MID + 1 <= r ? QueryMax(l, r, RS, MID + 1, gr) : -1
111 );
112 }
113}st;
114
115ll QueryMax(int s, int t){
116 ll ret(0);
117 while(top[s] != top[t]){
118 if(dep[top[s]] < dep[top[t]])swap(s, t);
119 ret = max(ret, st.QueryMax(dfn[top[s]], dfn[s]));
120 // printf("s = %d, t = %d, tps = %d, dfntp = %d, dfn = %d Max:%lld\n", s, t, top[s], dfn[top[s]], dfn[s], st.QueryMax(dfn[top[s]], dfn[s]));
121 s = fa[top[s]];
122 }if(dep[s] < dep[t])swap(s, t);
123 return max(ret, st.QueryMax(dfn[hson[t]], dfn[s]));
124}
125
126int main(){
127 // freopen("tree.in", "r", stdin);
128 // freopen("tree.out", "w", stdout);
129 N = read(), M = read();
130 for(int i = 1; i <= M; ++i){
131 int s = read(), t = read(), v = read();
132 edges.emplace_back(Edges{v, s, t, i});
133 qs[i] = {s, t, v};
134 }sort(edges.begin(), edges.end());
135 for(auto e : edges)
136 if(uf.Find(e.s) != uf.Find(e.t))
137 uf.Union(e.s, e.t),
138 head[e.s] = new Edge{head[e.s], e.t, e.val},
139 head[e.t] = new Edge{head[e.t], e.s, e.val},
140 intree[e.idx] = true,
141 origin += e.val;
142 dfs_edge_to_vertex();
143 dfs_pre();
144 dfs();//dfn[0] = 1;
145 st.Build();
146 // printf("%d\n", st.QueryMax(5, 5));
147 for(int i = 1; i <= M; ++i){
148 if(intree[i]){ans[i] = origin; continue;}
149 int s, t, v; tie(s, t, v) = qs[i];
150 // printf("Edge:%d, %d->%d max = %lld\n", i, s, t, QueryMax(s, t));
151 ans[i] = origin - QueryMax(s, t) + v;
152 }
153 for(int i = 1; i <= M; ++i)printf("%lld\n", ans[i]);
154 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
155 return 0;
156}
157
158template < typename T >
159inline T read(void){
160 T ret(0);
161 short flag(1);
162 char c = getchar();
163 while(c != '-' && !isdigit(c))c = getchar();
164 if(c == '-')flag = -1, c = getchar();
165 while(isdigit(c)){
166 ret *= 10;
167 ret += int(c - '0');
168 c = getchar();
169 }
170 ret *= flag;
171 return ret;
172}
173/*
1745 7
1751 2 3
1761 3 1
1771 4 5
1782 3 2
1792 5 3
1803 4 2
1814 5 4
182*/
update-2022_11_10 初稿