SegmentTreeMerging
#include <iostream>
#include <cstdio>
using namespace std;
template <class T>
T read() {
T re = 0;
char c = getchar();
bool negt = false;
while(c < '0' || c > '9')
negt |= (c == '-') , c = getchar();
while(c >= '0' && c <= '9')
re = (re << 1) + (re << 3) + c - '0' , c = getchar();
return negt ? -re : re;
}
const int N = 1e5 + 10 , M = 1e5 + 10 , logN = 20;
struct EDGE {
int to , nxt;
} ed[N * 2];
int head[N];
void addedge(int u , int v) {
static int cnt = 0;
++cnt;
ed[cnt].to = v , ed[cnt].nxt = head[u] , head[u] = cnt;
}
int fa[N];
namespace LCA {
int cnt;
int dep[N * 2] , fir[N] , id[N * 2];
int st[N * 2][30];
int Log2[N * 2];
void dfs(int x , int nowdep) {
++cnt;
fir[x] = cnt , dep[cnt] = nowdep , id[cnt] = x;
for(int i = head[x] ; i ; i = ed[i].nxt) {
int to = ed[i].to;
if(to == fa[x])continue;
fa[to] = x;
dfs(to , nowdep + 1);
++cnt;
dep[cnt] = nowdep , id[cnt] = x;
}
}
void Init() {
dfs(1 , 0);
for(int i = 2 ; i <= cnt ; i++)
Log2[i] = Log2[i - 1] + ((i & (i - 1)) == 0);
for(int i = 1 ; i <= cnt ; i++)
st[i][0] = i;
dep[0] = 0x3fffffff;
for(int j = 1 ; (1 << j) <= cnt ; j++)
for(int i = 1 ; i + (1 << j) <= cnt ; i++)
st[i][j] = (
dep[st[i][j - 1]] < dep[st[i + (1 << j - 1)][j - 1]] ? st[i][j - 1] : st[i + (1 << j - 1)][j - 1]
);
}
int query(int u , int v) {
u = fir[u] , v = fir[v];
if(u > v)swap(u , v);
int k = Log2[v - u + 1];
return id[
dep[st[u][k]] < dep[st[v - (1 << k) + 1][k]] ? st[u][k] : st[v - (1 << k) + 1][k]
];
}
}
struct SegmentTree {
#define ls(_) node[_].ls
#define rs(_) node[_].rs
struct Data {
int val , pos;
Data() {
val = pos = 0;
}
bool operator > (const Data &b) const {
return val != b.val ? (val > b.val) : (pos < b.pos);
}
};
struct node {
int l , r;
int ls , rs;
Data dat;
} node[N * logN * 4];
int newnode(int l , int r) {
static int cnt = 0;
++cnt , node[cnt].l = l , node[cnt].r = r;
if(l == r)node[cnt].dat.pos = l;
return cnt;
}
void update(int root) {
node[root].dat = (node[ls(root)].dat > node[rs(root)].dat ? node[ls(root)].dat : node[rs(root)].dat);
}
void change(int root , int pos , int dat) {
if(node[root].l == node[root].r) {
node[root].dat.val += dat;//*
return ;
}
int mid = (node[root].l + node[root].r) / 2;
if(pos <= mid)
change(ls(root) != 0 ? ls(root) : (ls(root) = newnode(node[root].l , mid)) , pos , dat);
else
change(rs(root) != 0 ? rs(root) : (rs(root) = newnode(mid + 1 , node[root].r)) , pos , dat);
update(root);
}
int query(int root) {
return node[root].dat.pos;
}
int merge(int root1 , int root2) {
if(root1 == 0)return root2;
if(root2 == 0)return root1;
if(node[root1].l == node[root1].r) {
node[root1].dat.val += node[root2].dat.val;
return root1;
}
// int l , r;
ls(root1) = merge(ls(root1) , ls(root2)) , rs(root1) = merge(rs(root1) , rs(root2));
// if(ls(root1) != 0 && ls(root2) != 0)
// l = merge(ls(root1) , ls(root2));
// else
// l = (ls(root1) != 0 ? ls(root1) : ls(root2));
//
// if(rs(root1) != 0 && rs(root2) != 0)
// r = merge(rs(root1) , rs(root2));
// else
// r = (rs(root1) == 0 ? rs(root1) : rs(root2));
// ls(root1) = l , rs(root2) = r;
update(root1);
return root1;
}
void vis(int root) {
if(root == 0)return ;
vis(ls(root));
if(node[root].l == node[root].r)
printf("%d : %d\n" , node[root].l , node[root].dat.val);
vis(rs(root));
}
#undef ls
#undef rs
} segT;
int root[N];
int n , m;
int ans[N];
void dfs(int x) {
for(int i = head[x] ; i ; i = ed[i].nxt) {
int to = ed[i].to;
if(to == fa[x])continue;
dfs(to);
root[x] = segT.merge(root[x] , root[to]);
}
ans[x] = segT.query(root[x]);
}
int main() {
n = read<int>() , m = read<int>();
for(int i = 1 ; i < n ; i++) {
int u = read<int>() , v = read<int>();
addedge(u , v) , addedge(v , u);
}
for(int i = 1 ; i <= n ; i++)
root[i] = segT.newnode(1 , 1e5);
LCA::Init();
while(m--) {
int u = read<int>() , v = read<int>() , ty = read<int>();
int lca = LCA::query(u , v);
segT.change(root[u] , ty , 1) , segT.change(root[v] , ty , 1);
segT.change(root[lca] , ty , -1) , segT.change(root[fa[lca]] , ty , -1);
}
dfs(1);
for(int i = 1 ; i <= n ; i++)
printf("%d\n" , ans[i]);
return 0;
}
StringHash
//http://noip.ybtoj.com.cn/contest/599/problem/2
#include <iostream>
#include <cstdio>
#define int long long
using namespace std;
typedef long long ll;
const int N = 2e5 + 10 , maxMod = 1e7 + 17;
const ll mod1 = 1e7 - 7 , mod2 = 1e7 + 7 , mod3 = 1e7 + 9;
const ll base1 = 131 , base2 = 1331 , base3 = 212;
int n , m;
char s[N];
bool vis1[maxMod] , vis2[maxMod] , vis3[maxMod] , vis4[maxMod];
template <ll base , ll mod>
int GetKey(int l , int r) {
static ll val[N] , basepow[N];
static bool Init = 0;
if(Init == 0) {
Init = 1;
basepow[0] = 1;
for(int i = 1 ; i <= n ; i++)
val[i] = (val[i - 1] * base + s[i]) % mod , basepow[i] = basepow[i - 1] * base % mod;
}
return (val[r] - val[l - 1] * basepow[r - l + 1] % mod + mod * 2) % mod;
}
signed main() {
// freopen("string.in" , "r" , stdin);
// freopen("string.out" , "w" , stdout);
scanf("%d %d" , &n , &m);
scanf("%s" , s + 1);
int ans = 0;
for(int i = 1 ; i + m - 1 <= n ; i++) {
int r = i + m - 1;
int k1 = GetKey<base1 , mod1>(i , r);
int k2 = GetKey<base2 , mod2>(i , r);
int k3 = GetKey<base3 , mod3>(i , r);
int k4 = GetKey<base1 ,mod3>(i , r);
if(!vis1[k1] || !vis2[k2] || !vis3[k3] || !vis4[k4]) {
// cout << i << '\n';
++ans;
vis1[k1] = 1;
vis2[k2] = vis3[k3] = vis4[k4] = 1;
}
}
cout << ans;
return 0;
}
树链剖分
#include <iostream>
#include <cstdio>
#define int long long
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
template <class T>
T read() {
T re = 0;
char c = getchar();
bool negt = false;
while(c < '0' || c > '9')
negt |= (c == '-') , c = getchar();
while(c >= '0' && c <= '9')
re = (re << 1) + (re << 3) + c - '0' , c = getchar();
return negt ? -re : re;
}
ll mod;
class SegmentTree {
#define ls(_) node[_].ls
#define rs(_) node[_].rs
private :
struct node{
int l , r , ls , rs;
ll dat , tag;
}node[4 * N];
int newnode() {
static int cnt = 0;
return ++cnt;
}
void push_up(int root) {
node[root].dat = node[ls(root)].dat + node[rs(root)].dat;
}
void push_down(int root) {
if(node[root].tag != 0) {
node[ls(root)].dat += node[root].tag * (node[ls(root)].r - node[ls(root)].l + 1);
node[ls(root)].tag += node[root].tag;
node[rs(root)].dat += node[root].tag * (node[rs(root)].r - node[rs(root)].l + 1);
node[rs(root)].tag += node[root].tag;
node[ls(root)].dat %= mod ,node[ls(root)].tag %= mod ,node[rs(root)].dat %= mod ,node[rs(root)].tag %= mod;
node[root].tag = 0;
node[0].tag = node[0].dat = 0;
}
}
public :
int build(int l , int r) {
int id = newnode();
node[id].l = l , node[id].r = r , node[id].dat = 0 , node[id].tag = 0;
if(l != r) {
int mid = (l + r) / 2;
ls(id) = build(l , mid);
rs(id) = build(mid + 1 , r);
}
return id;
}
void change(int root , int l , int r , ll dat) {
if(l > node[root].r || r < node[root].l)return ;
if(l <= node[root].l && r >= node[root].r) {
node[root].tag += dat , node[root].dat += (node[root].r - node[root].l + 1) * dat;
return ;
}
push_down(root);
change(ls(root) , l , r , dat);
change(rs(root) , l , r , dat);
push_up(root);
}
ll query(int root , int l , int r) {
if(l > node[root].r || r < node[root].l)return 0;
if(l <= node[root].l && r >= node[root].r)
return node[root].dat;
push_down(root);
return (query(ls(root) , l , r) + query(rs(root) , l , r)) % mod;
}
#undef ls
#undef rs
};
struct EDGE {
int to , nxt;
}ed[N * 2];
int head[N];
void addedge(int u , int v) {
static int cnt = 0;
++cnt;
ed[cnt].to = v , ed[cnt].nxt = head[u] , head[u] = cnt;
}
SegmentTree segT;
int segTr;
int n , m;
int root;
int dep[N] , initialVal[N] , id[N] , siz[N] , hvyson[N] , fa[N];
int top[N];
void dfs1(int x) {
dep[x] = dep[fa[x]] + 1;
siz[x] = 1;
for(int i = head[x] ; i ; i = ed[i].nxt) {
int to = ed[i].to;
if(to == fa[x])continue;
fa[to] = x;
dfs1(to );
siz[x] += siz[to];
}
for(int i = head[x] ; i ; i = ed[i].nxt) {
int to = ed[i].to;
if(to == fa[x])continue;
if(siz[to] > siz[hvyson[x]])
hvyson[x] = to;
}
}
void dfs2(int x , int Top) {
static int Time = 0;
id[x] = ++Time;
top[x] = Top;
if(hvyson[x] != 0)dfs2(hvyson[x] , top[x]);
for(int i = head[x] ; i ; i = ed[i].nxt) {
int to = ed[i].to;
if(to == fa[x] || to == hvyson[x])continue;
dfs2(to , to);
}
}
void Initialize() {
dfs1(root );
dfs2(root , 0);//*
segTr = segT.build(1 , n);
for(int i = 1 ; i <= n ; i++)
segT.change(segTr , id[i] , id[i] , initialVal[i]);
}
signed main() {
// freopen("P3384_2.in" , "r" , stdin);
// freopen("output.txt" , "w" , stdout);
n = read<int>() , m = read<int>() , root = read<int>() , mod = read<int>();
for(int i = 1 ; i <= n ; i++)initialVal[i] = read<int>() % mod;
for(int i = 1 ; i < n ; i++) {
int u = read<int>() , v = read<int>();
addedge(u , v) , addedge(v , u);
}
Initialize();
while(m--) {
int x , y;
ll sum = 0 , val;
switch(read<int>()) {
case 1:
x = read<int>() , y = read<int>() , val = read<ll>();
while(top[x] != top[y]) {//*
if(id[x] < id[y])swap(x , y);//*
segT.change(segTr , id[top[x]] , id[x] , val);
x = fa[top[x]];
}
if(id[x] > id[y])swap(x , y);
segT.change(segTr , id[x] , id[y] , val);
break;
case 2:
x = read<int>() , y = read<int>();
while(top[x] != top[y]) {//*
if(id[x] < id[y])swap(x , y);//*
sum += segT.query(segTr , id[top[x]] , id[x] );
sum %= mod;
x = fa[top[x]];
}
if(id[x] > id[y])swap(x , y);
sum += segT.query(segTr , id[x] , id[y]);
sum %= mod;
printf("%lld\n" , sum);
break;
case 3:
x = read<int>() , val = read<ll>();
segT.change(segTr , id[x] , id[x] + siz[x] - 1 , val);
break;
case 4:
x = read<int>();
printf("%lld\n" , segT.query(segTr , id[x] , id[x] + siz[x] - 1) % mod);
break;
}
}
return 0;
}
dijkstra
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <map>
using namespace std;
template <class T>
T read() {
T re = 0;
char c = getchar();
bool negt = false;
while(c < '0' || c > '9')
negt |= (c == '-') , c = getchar();
while(c >= '0' && c <= '9')
re = (re << 1) + (re << 3) + c - '0' , c = getchar();
return negt ? -re : re;
}
typedef long long ll;
const int N = 1e5 + 10 , M = 2e5 + 10;
struct EDGE {
int to , nxt;
ll len;
}ed[M];
int head[N];
void addedge(int u , int v , int len) {
static int cnt = 0;
++cnt;
ed[cnt].len = len , ed[cnt].to = v , ed[cnt].nxt = head[u] , head[u] = cnt;
}
int n , m , s;
ll dist[N];
bool vis[N];
priority_queue <pair<ll , int> >q;
int main() {
n = read<int>() , m = read<int>() , s = read<int>();
for(int i = 1 ; i <= m ; i++) {
int u = read<int>() , v = read<int>() , len = read<int>();
addedge(u , v , len);
}
memset(dist , 0x3f , sizeof(dist));
q.push(make_pair(0 , s));
while(!q.empty()) {
int u = (q.top()).second;
ll d = -(q.top()).first;
q.pop();
if(vis[u])continue;
vis[u] = true;
dist[u] = d;
for(int i = head[u] ; i ; i = ed[i].nxt) {
int to = ed[i].to;
if(vis[to])continue;
if(dist[to] > dist[u] + ed[i].len)
dist[to] = dist[u] + ed[i].len , q.push(make_pair(-dist[to] , to));
}
}
for(int i = 1 ; i <= n ; i++)
printf("%lld " , dist[i]);
return 0;
}
Gauss
#include <iostream>
#include <cstdio>
using namespace std;
template <class T>
T read() {
T re = 0;
char c = getchar();
bool negt = false;
while(c < '0' || c > '9')
negt |= (c == '-') , c = getchar();
while(c >= '0' && c <= '9')
re = (re << 1) + (re << 3) + c - '0' , c = getchar();
return negt ? -re : re;
}
const int N = 110;
int n;
double a[N][N];
bool Gauss() {
for(int i = 1 ; i <= n ; i++) {
if(a[i][i] == 0) {
bool Find = false;
for(int j = i + 1 ; j <= n ; j++)
if(a[j][i] != 0) {
swap(a[i] , a[j]) , Find = true;
break;
}
if(!Find)return false;
}
for(int j = 1 ; j <= n ; j++)
if(i != j) {
double mul = a[j][i] / a[i][i];
for(int k = 1 ; k <= n + 1 ; k++)
a[j][k] -= a[i][k] * mul;
}
}
return true;
}
int main() {
n = read<int>();
for(int i = 1 ; i <= n ; i++)
for(int j = 1 ; j <= n + 1 ; j++)
a[i][j] = read<int>();
if(Gauss()) {
for(int i = 1 ; i <= n ; i++)
printf("%.2lf\n" , a[i][n + 1] / a[i][i]);
}
else puts("No Solution");
return 0;
}
KMP
//https://www.luogu.com.cn/problem/P3375
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 1e6 + 10;
int n , m;
char s[N] , t[N];
int nxt[N];
int main() {
scanf("%s" , s + 1);
scanf("%s" , t + 1);
n = strlen(s + 1) , m = strlen(t + 1);
nxt[1] = 0;
for(int i = 2 , j = nxt[1] ; i <= m ; i++) {
while(j != 0 && t[i] != t[j + 1])j = nxt[j];
if(t[i] == t[j + 1])++j;
nxt[i] = j;
}
for(int i = 1 , j = 0 ; i <= n ; i++) {
while(j != 0 && s[i] != t[j + 1] && j != m)j = nxt[j];
if(s[i] == t[j + 1])++j;
if(j == m) {
printf("%d\n" , i - m + 1);
j = nxt[j];
}
}
for(int i = 1 ; i <= m ; i++)
printf("%d " , nxt[i]);
return 0;
}
LCA-RMQ
//https://www.luogu.com.cn/problem/P3379#submit
#include <iostream>
#include <cstdio>
using namespace std;
template <class T>
T read() {
T re = 0;
char c = getchar();
bool negt = false;
while(c < '0' || c > '9')
negt |= (c == '-') , c = getchar();
while(c >= '0' && c <= '9')
re = (re << 1) + (re << 3) + c - '0' , c = getchar();
return negt ? -re : re;
}
const int N = 500010;
int head[N];
struct EDGE {
int to , nxt;
} ed[N * 2];
void addedge(int u , int v) {
static int cnt = 0;
++cnt;
ed[cnt].to = v , ed[cnt].nxt = head[u] , head[u] = cnt;
}
int cnt;
int dep[N * 2] , fir[N] , id[N * 2];//attention: array size
int st[N * 2][30];
int Log2[N * 2];
int n , m , root;
void dfs(int x , int fa , int nowd) {
++cnt;
id[cnt] = x , dep[cnt] = nowd , fir[x] = cnt;
for(int i = head[x] ; i ; i = ed[i].nxt) {
int to = ed[i].to;
if(to == fa)continue;
dfs(to , x , nowd + 1);
++cnt;
id[cnt] = x , dep[cnt] = nowd;
}
}
void INIT() {
dfs(root , 0 , 1);
for(int i = 1 ; i <= cnt ; i++)
st[i][0] = i;
for(int i = 2 ; i <= cnt ; i++)
Log2[i] = Log2[i - 1] + ((i & (i - 1)) == 0);
dep[0] = 0x3fffffff;
for(int j = 1 ; (1 << j) <= cnt ; j++)
for(int i = 1 ; i + (1 << j) <= cnt ; i++)
st[i][j] =
dep[st[i][j - 1]] < dep[st[i + (1 << j - 1)][j - 1]] ?
st[i][j - 1] : st[i + (1 << j - 1)][j - 1];
}
int query(int u , int v) {
u = fir[u] , v = fir[v];
if(u > v) {
int tmp = u;
u = v , v = tmp;
}
int k = Log2[v - u + 1];
return id[
dep[st[u][k]] < dep[st[v - (1 << k) + 1][k]] ?
st[u][k] : st[v - (1 << k) + 1][k]
];
}
int main() {
n = read<int>() , m = read<int>() , root = read<int>();
for(int i = 1 ; i < n ; i++) {
int u = read<int>() , v = read<int>();
addedge(u , v) , addedge(v , u);
}
INIT();
// return 0;
while(m --) {
printf("%d\n" , query(read<int>() , read<int>()));
}
return 0;
}
SegmentTree
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
template <class T>
T read() {
T re = 0;
char c = getchar();
bool negt = false;
while(c < '0' || c > '9')
negt |= (c == '-') , c = getchar();
while(c >= '0' && c <= '9')
re = (re << 1) + (re << 3) + c - '0' , c = getchar();
return negt ? -re : re;
}
class SegmentTree {
#define ls(_) node[_].ls
#define rs(_) node[_].rs
private :
struct node{
int l , r , ls , rs;
ll dat , tag;
}node[4 * N];
int newnode() {
static int cnt = 0;
return ++cnt;
}
void push_up(int root) {
node[root].dat = node[ls(root)].dat + node[rs(root)].dat;
}
void push_down(int root) {
if(node[root].tag != 0) {
node[ls(root)].dat += node[root].tag * (node[ls(root)].r - node[ls(root)].l + 1);
node[ls(root)].tag += node[root].tag;
node[rs(root)].dat += node[root].tag * (node[rs(root)].r - node[rs(root)].l + 1);
node[rs(root)].tag += node[root].tag;
// node[ls(root)].dat %= mod ,node[ls(root)].tag %= mod ,node[rs(root)].dat %= mod ,node[rs(root)].tag %= mod;
node[root].tag = 0;
node[0].tag = node[0].dat = 0;
}
}
public :
int build(int l , int r) {
int id = newnode();
node[id].l = l , node[id].r = r , node[id].dat = 0 , node[id].tag = 0;
if(l != r) {
int mid = (l + r) / 2;
ls(id) = build(l , mid);
rs(id) = build(mid + 1 , r);
}
return id;
}
void change(int root , int l , int r , ll dat) {
if(l > node[root].r || r < node[root].l)return ;
if(l <= node[root].l && r >= node[root].r) {
node[root].tag += dat , node[root].dat += (node[root].r - node[root].l + 1) * dat;
return ;
}
push_down(root);
change(ls(root) , l , r , dat);
change(rs(root) , l , r , dat);
push_up(root);
}
ll query(int root , int l , int r) {
if(l > node[root].r || r < node[root].l)return 0;
if(l <= node[root].l && r >= node[root].r)
return node[root].dat;
push_down(root);
return (query(ls(root) , l , r) + query(rs(root) , l , r));
}
#undef ls
#undef rs
};
SegmentTree segT;
int segTr;
int n , m;
int main() {
// freopen("P3384_2.in" , "r" , stdin);
n = read<int>() , m = read<int>();
segTr = segT.build(1 , n);
// m = 10;
for(int i = 1 ; i <= n ; i++)segT.change(segTr , i , i , read<int>());
while(m--) {
int l , r;
ll k;
if(read<int>() == 1)
l = read<int>() , r = read<int>() , k = read<ll>() , segT.change(segTr , l , r , k);
else
l = read<int>() , r = read<int>() , printf("%lld\n" , segT.query(segTr , l , r));
}
return 0;
}
SimulateAnneal
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
const int N = 1010;
struct node {
int x , y , m;
}a[N];
int n;
#define rand() (rand() % 0x7fff)
const int myRAND_MAX = 0x7fff;
const double InitialT = 30000;
const double decrease = 0.993;
const double minT = 1e-3 / myRAND_MAX / 3e2;
double calc(double x , double y) {
double E = 0;
for(int i = 1 ; i <= n ; i++)
E += sqrt((a[i].x - x) * (a[i].x - x) + (a[i].y - y) * (a[i].y - y)) * a[i].m;
return E;
}
double ansx , ansy , ansE = 1e18;
void SA() {
double x = ansx , y = ansy;
for(double t = InitialT ; t > minT ; t *= decrease) {
double newx = x + (rand() * 2 - myRAND_MAX) * t;
double newy = y + (rand() * 2 - myRAND_MAX) * t;
double newE = calc(newx , newy);
double delT = newE - ansE;
if(delT < 0)
ansx = x = newx , ansy = y = newy , ansE = newE;
else if(exp(-delT / t) * myRAND_MAX > rand())
x = newx , y = newy ;
}
}
int main() {
srand(19260817);
scanf("%d" , &n);
for(int i = 1 ; i <= n ; i++)
scanf("%d %d %d" , &a[i].x , &a[i].y , &a[i].m);
int times = 3e7 / (n * (log(minT / InitialT) / log(decrease)));
if(times > 100) times = 100;
for(int i = 1 ; i <= times ; i++)
SA();
printf("%.3lf %.3lf" , ansx , ansy);
return 0;
}