代码模板
UnionRE
·
·
科技·工程
Codes
代码模板
//#pragma GCC optimize("Ofast,no-stack-protector")
//#define _CRT_SECURE_NO_WARNINGS
//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
//#pragma GCC optimize("Ofast")
//#pragma GCC optimize("inline")
//#pragma GCC optimize("-fgcse")
//#pragma GCC optimize("-fgcse-lm")
//#pragma GCC optimize("-fipa-sra")
//#pragma GCC optimize("-ftree-pre")
//#pragma GCC optimize("-ftree-vrp")
//#pragma GCC optimize("-fpeephole2")
//#pragma GCC optimize("-ffast-math")
//#pragma GCC optimize("-fsched-spec")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC optimize("-falign-jumps")
//#pragma GCC optimize("-falign-loops")
//#pragma GCC optimize("-falign-labels")
//#pragma GCC optimize("-fdevirtualize")
//#pragma GCC optimize("-fcaller-saves")
//#pragma GCC optimize("-fcrossjumping")
//#pragma GCC optimize("-fthread-jumps")
//#pragma GCC optimize("-funroll-loops")
//#pragma GCC optimize("-fwhole-program")
//#pragma GCC optimize("-freorder-blocks")
//#pragma GCC optimize("-fschedule-insns")
//#pragma GCC optimize("inline-functions")
//#pragma GCC optimize("-ftree-tail-merge")
//#pragma GCC optimize("-fschedule-insns2")
//#pragma GCC optimize("-fstrict-aliasing")
//#pragma GCC optimize("-fstrict-overflow")
//#pragma GCC optimize("-falign-functions")
//#pragma GCC optimize("-fcse-skip-blocks")
//#pragma GCC optimize("-fcse-follow-jumps")
//#pragma GCC optimize("-fsched-interblock")
//#pragma GCC optimize("-fpartial-inlining")
//#pragma GCC optimize("no-stack-protector")
//#pragma GCC optimize("-freorder-functions")
//#pragma GCC optimize("-findirect-inlining")
//#pragma GCC optimize("-fhoist-adjacent-loads")
//#pragma GCC optimize("-frerun-cse-after-loop")
//#pragma GCC optimize("inline-small-functions")
//#pragma GCC optimize("-finline-small-functions")
//#pragma GCC optimize("-ftree-switch-conversion")
//#pragma GCC optimize("-foptimize-sibling-calls")
//#pragma GCC optimize("-fexpensive-optimizations")
//#pragma GCC optimize("-funsafe-loop-optimizations")
//#pragma GCC optimize("inline-functions-called-once")
//#pragma GCC optimize("-fdelete-null-pointer-checks")
//include:
#include <bits/stdc++.h>
#include<bits/extc++.h>
using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;
// #include<ext/pb_ds/assoc_container.hpp>
// #include<ext/pb_ds/tree_policy.hpp>//用tree
// #include<ext/pb_ds/hash_policy.hpp>//用hash
// #include<ext/pb_ds/trie_policy.hpp>//用trie
// #include<ext/pb_ds/priority_queue.hpp>//用priority_queue
// using namespace __gnu_pbds;
// __gnu_pbds::priority_queue<T, Compare, Tag, Allocator>
// __gnu_pbds::tree<Key, Mapped, Cmp_Fn = std::less<Key>, Tag = rb_tree_tag,
// Node_Update = null_tree_node_update,
// Allocator = std::allocator<char>>
#define mp make_pair
#define cchash cc_hash_table<int,bool>
#define gphash gp_hash_table<int,bool>
typedef tree<long long,null_type,less<long long>,rb_tree_tag,tree_order_statistics_node_update> bbtr;//平衡树
//tree不可重!!!
//存储的类型:long long
//映射类型:null_type,无映射(低版本g++为null_mapped_type)
//顺序:less<long long>,从小到大排序
//rb_tree_tag,红黑树
//更新方式 :tree_order_statistics_node_update,更新节点的顺序统计信息
#define pqueue __gnu_pbds::priority_queue
#define grt greater//greater<int>小根堆
#define pair_h pairing_heap_tag
#define thin_h thin_heap_tag
#define bino_h binomial_heap_tag
#define rcbino_h rc_binomial_heap_tag
#define binary_h binary_heap_tag
typedef trie<string,null_type,trie_string_access_traits<>,pat_trie_tag,trie_prefix_search_node_update> tr;
/*
pairing_heap_tag
thin_heap_tag
binomial_heap_tag
rc_binomial_heap_tag
binary_heap_tag
*/
//#define endl '\n'
#define pow fastpow
//#define getchar getchar_unlocked
//#define putchar putchar_unlocked
//unlocked WINDOWS会报错
inline int read(){
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=(x << 1) + (x << 3)+ch-48;ch=getchar();}
return x*f;
}//快读
inline void write(int x){
if(x<0){putchar('-');x=-x;}
if(x>9)write(x/10);
putchar(x%10+'0');
}//快输
//常数较小的快输:
inline void fastwrite(int x) {
static int sta[35];
int top =0;
do{sta[top++]=x%10,x/=10;}while (x);
while(top) putchar(sta[--top]+48);
}
struct cnt_trie{
vector<vector<int>>ch;
vector<int>cnt;
int ct=0;
int gn_map[128];
//如果用全局数组,不用vector,常数约为1/2
void clear(){
ch.clear();
cnt.clear();
ch.push_back(vector<int>(65, 0)); // 初始化根节点
cnt.push_back(0);
ct=0;
}
cnt_trie(){cnt_trie::init_gn();clear();}
void init_gn() {
for(int i=0;i<128;i++) gn_map[i]=-1;
for(char c='A';c<='Z';c++) gn_map[c]=c-'A';
for(char c='a';c<='z';c++) gn_map[c]=c-'a'+26;
for(char c='0';c<='9';c++) gn_map[c]=c-'0'+52;
}
inline int gn(char x){return gn_map[(int)x];}
void insert(string str){
int p=0,l=str.size();
for(int i=0;i<l;i++){
int c=gn(str[i]);
if(!ch[p][c]){
ch.push_back(vector<int>(65, 0));//全局数组就不用这两个push_back,直接用
cnt.push_back(0);
ch[p][c]=++ct;
}
p=ch[p][c];
cnt[p]++;
}
}
int find_cnt(string str){
int p=0,l=str.size();
for(int i=0;i<l;i++){
int c=gn(str[i]);
if(!ch[p][c]) return 0;
p=ch[p][c];
}
return cnt[p];
}
pair<int,int> find_range(string str){
int p=0,l=str.size();
for(int i=0;i<l;i++){
int c=gn(str[i]);
if(!ch[p][c]) return {0,0};
p=ch[p][c];
}
return {p,ct};
}
};
namespace fast_io{
const int fread_cnt=(1<<20);
const int fwrite_cnt=(1<<20);
class fast_read{
private:
char buf_in[fread_cnt],*p1,*p2;
inline char gc(){return (p1==p2&&(p2=(p1=buf_in)+fread(buf_in,1,fread_cnt,stdin),p1==p2)?EOF:*p1++);}
inline bool read_bool(){char ch=gc();while(ch<'0'||ch>'1'){ch=gc();}return (ch=='1');}
inline char read_ch(){char ch=gc();while(ch==' '||ch=='\r'||ch=='\n'||ch=='\t'){ch=gc();}return ch;}
inline string read_string(){
string s;char ch=gc();while(ch==' '||ch=='\r'||ch=='\n'||ch=='\t'){ch=gc();}
while(ch!=' '&&ch!='\r'&&ch!='\n'&&ch!='\t'){s+=ch;ch=gc();}return s;
}
template <typename T>
inline T read_int(){
T x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){f=(ch=='-')?-f:f;ch=gc();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=gc();}
return x*f;
}
template <typename T>
inline T read_unsigned(){
T x=0;char ch=gc();while(ch<'0'||ch>'9'){ch=gc();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=gc();}
return x;
}
template <typename T>
inline T read_float(){
T x=0,f=1,c=1;char ch=gc();
while(ch<'0'||ch>'9'){f=(ch=='-')?-f:f;ch=gc();}
while(ch>='0'&&ch<='9'){x=x*10+(ch^48);ch=gc();}
if(ch=='.'){ch=gc();while(ch>='0'&&ch<='9'){c/=10;x+=c*(ch^48);ch=gc();}}
return x*f;
}
public:
fast_read& operator >> (bool &valx){valx=read_bool();return *this;}
fast_read& operator >> (char &valx){valx=read_ch();return *this;}
fast_read& operator >> (string &valx){valx=read_string();return *this;}
fast_read& operator >> (float &valx){valx=read_float<float>();return *this;}
fast_read& operator >> (double &valx){valx=read_float<double>();return *this;}
fast_read& operator >> (long double &valx){valx=read_float<long double>();return *this;}
fast_read& operator >> (short &valx){valx=read_int<short>();return *this;}
fast_read& operator >> (int &valx){valx=read_int<int>();return *this;}
fast_read& operator >> (long &valx){valx=read_int<long>();return *this;}
fast_read& operator >> (long long &valx){valx=read_int<long long>();return *this;}
fast_read& operator >> (unsigned short &valx){valx=read_unsigned<unsigned short>();return *this;}
fast_read& operator >> (unsigned int &valx){valx=read_unsigned<unsigned int>();return *this;}
fast_read& operator >> (unsigned long &valx){valx=read_unsigned<unsigned long>();return *this;}
fast_read& operator >> (unsigned long long &valx){valx=read_unsigned<unsigned long long>();return *this;}
}fin;
class fast_write{
private:
char buf_out[fwrite_cnt],*p=buf_out;
inline void write_bool(bool x){char ch=(x==1)?'1':'0';pc(ch);}
inline void write_ch(char x){char ch=x;pc(ch);}
inline void write_string(string s){for(string::iterator it=s.begin();it!=s.end();it=next(it)){pc(*it);}}
template <typename T>
inline void write_int(T x){
if(x<(T)0){pc('-');x=-x;}
if(x>=10){write_int(x/10);}pc((x%10)^48);
}
template <typename T>
inline void write_unsigned(T x){
if(x>=10){write_unsigned(x/10);}pc((x%10)^48);
}
template <typename T>
inline void write_float(T x){
if(x<(T)0)pc('-'),x=-x;
write_int((int)x);pc('.');x-=(int)x;
while(x!=0){x*=10;pc((int)x^48);x-=(int)x;}
}
public:
inline void pc(char ch){if(p-buf_out==fwrite_cnt){fwrite(buf_out,1,fwrite_cnt,stdout),p=buf_out;}*p=ch;++p;}
inline void flush(){fwrite(buf_out,1,p-buf_out,stdout);p=buf_out;}
inline fast_write& operator << (bool valx){write_bool(valx);return *this;}
inline fast_write& operator << (char valx){write_ch(valx);return *this;}
inline fast_write& operator << (string valx){write_string(valx);return *this;}
inline fast_write& operator << (float valx){write_float<float>(valx);return *this;}
inline fast_write& operator << (double valx){write_float<double>(valx);return *this;}
inline fast_write& operator << (long double valx){write_float<long double>(valx);return *this;}
inline fast_write& operator << (short valx){write_int<short>(valx);return *this;}
inline fast_write& operator << (int valx){write_int<int>(valx);return *this;}
inline fast_write& operator << (long valx){write_int<long>(valx);return *this;}
inline fast_write& operator << (long long valx){write_int<long long>(valx);return *this;}
inline fast_write& operator << (unsigned short valx){write_unsigned<unsigned short>(valx);return *this;}
inline fast_write& operator << (unsigned int valx){write_unsigned<unsigned int>(valx);return *this;}
inline fast_write& operator << (unsigned long valx){write_unsigned<unsigned long>(valx);return *this;}
inline fast_write& operator << (unsigned long long valx){write_unsigned<unsigned long long>(valx);return *this;}
inline fast_write& operator << (fast_write& (*func)(fast_write&)){return func(*this);}
}fout;inline fast_write& endl(fast_write& fastout){fastout.pc('\n');fastout.flush();return fastout;}
}using namespace fast_io;
#define int long long
int Reverse_order_pairs=0;//逆序对,个数
const int MAXN=1000001;
int a[MAXN],c[MAXN];
class Graph {//DAG有向无环图
private:
int n;
vector<unordered_map<int, int>> adj; // 邻接表,adj[u][v] = 初始边权w0
vector<int> add_in; // 每个节点的入边附加权值
vector<int> add_out; // 每个节点的出边附加权值
vector<int> topo; // 拓扑序
vector<int> topo_index; // 节点在拓扑序中的索引
vector<int> in_degree; // 节点的入度
public:
Graph(int num_nodes) : n(num_nodes), adj(num_nodes), add_in(num_nodes, 0),
add_out(num_nodes, 0), topo_index(num_nodes, -1),
in_degree(num_nodes, 0) {}
// 添加有向边 u->v,初始权值为w
void addedge(int u, int v, int w) {
if (u < 0 || u >= n || v < 0 || v >= n) return;
if (adj[u].find(v) == adj[u].end()) {
adj[u][v] = w;
in_degree[v]++;
} else {
adj[u][v] = w; // 如果边已存在,覆盖权值
}
}
// 构建拓扑序
void build_topo() {
topo.clear();
vector<int> in_deg = in_degree; // 复制入度数组
queue<int> q;
for (int i = 0; i < n; i++) {
if (in_deg[i] == 0) {
q.push(i);
}
}
while (!q.empty()) {
int u = q.front(); q.pop();
topo.push_back(u);
for (auto& edge : adj[u]) {
int v = edge.first;
if (--in_deg[v] == 0) {
q.push(v);
}
}
}
// 设置拓扑序索引
for (int i = 0; i < topo.size(); i++) {
topo_index[topo[i]] = i;
}
}
// 修改单边(u->v)的初始权值,加上delta
void change_edge(int u, int v, int delta) {
if (u < 0 || u >= n || v < 0 || v >= n) return;
if (adj[u].find(v) != adj[u].end()) {
adj[u][v] += delta;
}
}
// 修改节点v的所有入边,每条边加上delta
void change_in_edges(int v, int delta) {
if (v >= 0 && v < n) {
add_in[v] += delta;
}
}
// 修改节点u的所有出边,每条边加上delta
void change_out_edges(int u, int delta) {
if (u >= 0 && u < n) {
add_out[u] += delta;
}
}
// 查询s到t的最短路径长度
int shortest_path(int s, int t) {
if (s < 0 || s >= n || t < 0 || t >= n) return INT_MIN;
if (topo.empty() || topo_index[s] == -1) return INT_MIN;
vector<long long> dist(n, LLONG_MAX / 2); // 防止溢出
dist[s] = 0;
int start_idx = topo_index[s];
for (int i = start_idx; i < topo.size(); i++) {
int u = topo[i];
if (dist[u] == LLONG_MAX / 2) continue; // 不可达节点
for (auto& edge : adj[u]) {
int v = edge.first;
int w0 = edge.second;
long long actual_weight = (long long)w0 + add_out[u] + add_in[v];
if (dist[u] + actual_weight < dist[v]) {
dist[v] = dist[u] + actual_weight;
}
}
}
return (dist[t] >= LLONG_MAX / 2) ? INT_MIN : (int)dist[t];
}
// 查询s到t的最长路径长度
int longest_path(int s, int t) {
if (s < 0 || s >= n || t < 0 || t >= n) return INT_MIN;
if (topo.empty() || topo_index[s] == -1) return INT_MIN;
vector<long long> dist(n, LLONG_MIN);
dist[s] = 0;
int start_idx = topo_index[s];
for (int i = start_idx; i < topo.size(); i++) {
int u = topo[i];
if (dist[u] == LLONG_MIN) continue; // 不可达节点
for (auto& edge : adj[u]) {
int v = edge.first;
int w0 = edge.second;
long long actual_weight = (long long)w0 + add_out[u] + add_in[v];
if (dist[u] + actual_weight > dist[v]) {
dist[v] = dist[u] + actual_weight;
}
}
}
return (dist[t] == LLONG_MIN) ? INT_MIN : (int)dist[t];
}
};
const long long maxPrime=6000010,maxNumber=10000100;
bitset<maxNumber> isPrime;
int Prime[maxPrime];//质数
int cntPrime=0;
void GetPrime(int n){
isPrime.set();
isPrime[1]=0;
for(int i=2;i<=n;i++){
if(isPrime[i])Prime[++cntPrime]=i;
for(int j=1;j<=cntPrime&&i*Prime[j]<=n;j++) {
isPrime[i*Prime[j]]=0;
if(i%Prime[j]==0)break;
}
}
}
//支持对a数组排序
void MergeSort(int beg,int end)//begin&end
{
if(beg==end)
return;
int mid=(beg+end)/2,i=beg,j=mid+1,k=beg;
MergeSort(beg,mid),MergeSort(mid+1,end);
while(i<=mid&&j<=end)
if(a[i]<=a[j])
c[k++]=a[i++];
else{
c[k++]=a[j++];
Reverse_order_pairs+=mid-i+1;//左边即个数
}//inplace_merge();
while(i<=mid)c[k++]=a[i++];
while(j<=end)c[k++]=a[j++];
for(int x=beg;x<=end;x++)a[x]=c[x];
} //归并排序
namespace largetype{
class largeint{
private:
string num;
bool isNegative;
public:
largeint():num("0"),isNegative(false){}
largeint(const string& s){
if(s.empty()){
num="0";
isNegative=false;
return;
}
isNegative=(s[0]=='-');
num=isNegative?s.substr(1):s;
}
largeint(int n){
if(n==0){
num="0";
isNegative=false;
return;
}
isNegative=(n<0);
num=to_string(abs(n));
}
string getNum()const{return num;}
bool getIsNegative()const{return isNegative;}
bool operator<(const largeint& other)const{
if(isNegative!=other.isNegative)return isNegative;
if(num.length()!=other.num.length())
return isNegative?(num.length()>other.num.length()):(num.length()<other.num.length());
return isNegative?(num>other.num):(num<other.num);
}
bool operator==(const largeint& other)const{return num==other.num&&isNegative==other.isNegative;}
bool operator<=(const largeint& other)const{return *this<other||*this==other;}
bool operator>(const largeint& other)const{return !(*this<=other);}
bool operator>=(const largeint& other)const{return !(*this<other);}
largeint operator+(const largeint& other)const{
if(isNegative==other.isNegative){
string a=num,b=other.num;
int i=a.length()-1,j=b.length()-1,carry=0;
string res;
while(i>=0||j>=0||carry){
int x=(i>=0)?(a[i--]-'0'):0;
int y=(j>=0)?(b[j--]-'0'):0;
int sum=x+y+carry;
res.push_back(sum%10+'0');
carry=sum/10;
}
reverse(res.begin(),res.end());
largeint result(res);
result.isNegative=isNegative;
return result;
}else{
if(isNegative){
largeint temp=*this;
temp.isNegative=false;
return other-temp;
}else{
largeint temp=other;
temp.isNegative=false;
return *this-temp;
}
}
}
largeint operator-(const largeint& other)const{
if(isNegative!=other.isNegative){
largeint temp=other;
temp.isNegative=isNegative;
return *this+temp;
}
string a=num,b=other.num;
bool resNegative=false;
if((isNegative&&*this>other)||(!isNegative&&*this<other)){
swap(a,b);
resNegative=true;
}
int i=a.length()-1,j=b.length()-1,borrow=0;
string res;
while(i>=0||j>=0){
int x=(i>=0)?(a[i--]-'0'):0;
int y=(j>=0)?(b[j--]-'0'):0;
int diff=x-y-borrow;
if(diff<0){
diff+=10;
borrow=1;
}else{
borrow=0;
}
res.push_back(diff+'0');
}
while(res.length()>1&&res.back()=='0')res.pop_back();
reverse(res.begin(),res.end());
largeint result(res);
result.isNegative=resNegative;
return result;
}
largeint operator*(const largeint& other)const{
string a=num,b=other.num;
int m=a.length(),n=b.length();
vector<int> res(m+n,0);
for(int i=m-1;i>=0;i--){
for(int j=n-1;j>=0;j--){
int mul=(a[i]-'0')*(b[j]-'0');
int sum=mul+res[i+j+1];
res[i+j+1]=sum%10;
res[i+j]+=sum/10;
}
}
string resultStr;
for(int num:res){
if(!(resultStr.empty()&&num==0)){
resultStr.push_back(num+'0');
}
}
if(resultStr.empty())resultStr="0";
largeint result(resultStr);
result.isNegative=isNegative^other.isNegative;
return result;
}
void write()const{
if(isNegative)cout<<"-";
cout<<num;
}
};
}
using namespace largetype;
struct fantastic {//这个也可以
int len,s[9999];
fantastic(){
memset(s,0,sizeof(s));
len=1;
}
fantastic operator=(const char*num){
len=strlen(num);
for(int i=0;i<len;++i)
s[i]=num[len-i-1]-'0';
return *this;
}
fantastic operator=(const int num){
char a[9999];
sprintf(a,"%lld",num);
*this=a;
return *this;
}
fantastic (const int num){*this=num;}
fantastic (const char * num){*this=num;}
fantastic operator+(const fantastic &a) {
fantastic c;
c.len=max(len,a.len)+1;
for(int i=0,x=0;i<c.len;++i)
{
c.s[i]=s[i]+a.s[i]+x;
x=c.s[i]/10;
c.s[i]=c.s[i]%10;
}
if(c.s[c.len-1]==0)
--c.len;
return c;
}
fantastic operator * (const fantastic &x) {
fantastic c;
c.len=len+x.len;
for(int i=0;i<len;++i)
for(int j=0;j<x.len;++j)
{
c.s[i+j]+=s[i]*x.s[j];
c.s[i+j+1]+=c.s[i+j]/10;
c.s[i+j]%=10;
}
if(c.s[c.len-1]==0)
--c.len;
return c;
}
};
//另一种快读
/*
#include <bits/stdc++.h>
using lint = long long;
// #define DEBUG 1 // 调试开关
struct IO {
#define MAXSIZE (1 << 20)
#define isdigit(x) (x >= '0' && x <= '9')
char buf[MAXSIZE], *p1, *p2;
char pbuf[MAXSIZE], *pp;
#if DEBUG
#else
IO() : p1(buf), p2(buf), pp(pbuf) {}
~IO() { fwrite(pbuf, 1, pp - pbuf, stdout); }
#endif
char gc() {
#if DEBUG // 调试,可显示字符
return getchar();
#endif
if (p1 == p2) p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin);
return p1 == p2 ? ' ' : *p1++;
}
bool blank(char ch) {
return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
}
template <class T>
T read(T &x) {
double tmp = 1;
bool sign = 0;
x = 0;
char ch = gc();
for (; !isdigit(ch); ch = gc())
if (ch == '-') sign = 1;
for (; isdigit(ch); ch = gc()) x = x * 10 + (ch - '0');
if (ch == '.')
for (ch = gc(); isdigit(ch); ch = gc())
tmp /= 10.0, x += tmp * (ch - '0');
if (sign) x = -x;
return x;
}
void read(char *s) {
char ch = gc();
for (; blank(ch); ch = gc());
for (; !blank(ch); ch = gc()) *s++ = ch;
*s = 0;
}
void read(char &c) { for (c = gc(); blank(c); c = gc()); }
void push(const char &c) {
#if DEBUG // 调试,可显示字符
putchar(c);
#else
if (pp - pbuf == MAXSIZE) fwrite(pbuf, 1, MAXSIZE, stdout), pp = pbuf;
*pp++ = c;
#endif
}
template <class T>
void write(T x) {
if (x < 0) x = -x, push('-'); // 负数输出
static T sta[35];
T top = 0;
do {
sta[top++] = x % 10, x /= 10;
} while (x);
while (top) push(sta[--top] + '0');
}
template <class T>
void write(T x, char lastChar) {
write(x), push(lastChar);
}
} io;
int main() {
int n = io.read(n);
lint sum = 0;
for (int t; n; --n) sum += io.read(t);
io.write(sum, '\n');
return 0;
}
*/
int Mod;//支持输入模值
int fastpow(int a,int b) {
if(b==0)return 1;
int sum=1;
while(b) {
if(b&1) sum=sum*a%Mod;
a=a*a%Mod,b>>=1;
}
return sum;
}
//GetPrime(MAXP);MAXP为查询范围(查询到质数的最大值<=MAXP)
void FindPrime(){//查询质数
int k;
k=read();
write(Prime[k]);
puts("");
return;
}
signed main(){
//ios::sync_with_stdio(0);
//cin.tie(0);
//cout.tie(0);
//TODO
int n;//个数
int node_cnt,edge_cnt;//节点个数
cin>>node_cnt>>edge_cnt;
Graph dag(node_cnt);
while(edge_cnt--){
int u,v,w;
cin>>u>>v>>w;
dag.addedge(u,v,w);
}
dag.build_topo();
// cin>>n;
// for(int i=1;i<=n;i++)cin>>a[i];
// MergeSort(1,n);
int order_pairs=n*(n-1)/2-Reverse_order_pairs;
//顺序对(请先MergeSort)
// cout<<order_pairs;
return 0;
}
高精度python卡法
from decimal import *
import sys
setcontext(Context(prec=2000000, Emax=2000000, Emin=0))
print((Decimal(sys.stdin.readline())-Decimal(sys.stdin.readline())))
分块模板
#include<bits/stdc++.h>
#define int long long
#define sint int
using namespace std;
const int MAXN=1000010;
int L[MAXN],R[MAXN],s[MAXN],a[MAXN],pos[MAXN],add[MAXN];
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}//快读
inline void write(int x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
write(x/10);
putchar(x%10+'0');
}//快输
inline void update(int x,int y,int k){//在x,y范围每个内增加k
int p=pos[x],q=pos[y];
if(p==q){
for(int i=x;i<=y;i++)a[i]+=k;
s[p]=s[p]+(y-x+1)*k;
return;
}
for(int i=p+1;i<=q-1;i++){
add[i]+=k;
s[i]=s[i]+(R[i]-L[i]+1)*k;
}
for(int i=x;i<=R[p];i++)a[i]+=k;
s[p]=s[p]+(R[p]-x+1)*k;
for(int i=L[q];i<=y;i++){
a[i]+=k;
s[q]+=k;
}
}
int select(int x,int y){
int p=pos[x],q=pos[y];
int ans=0;
if(p==q){
for(int i=x;i<=y;i++)ans+=a[i]+add[p];
return ans;
}
else {
for(int i=x;i<=R[p];i++)ans+=a[i]+add[p];//左不完整块
for(int i=p+1;i<=q-1;i++)ans+=s[i];//中间完整块
for(int i=L[q];i<=y;i++)ans+=a[i]+add[q];//右不完整块
return ans;
}
}
int n,m,opt;
signed main(){
n=read();m=read();
for(int i=1;i<=n;i++){
a[i]=read();
}
int t=sqrt(n);
for(int i=1;i<=t;i++){
L[i]=t*(i-1)+1;
R[i]=t*i;
for(int j=L[i];j<=R[i];j++)pos[j]=i;
}
if(R[t]<n){
t++;
L[t]=R[t-1]+1;
R[t]=n;
for(int i=L[t];i<=R[t];i++)pos[i]=t;
}
for(int i=1;i<=t;i++){
for(int j=L[i];j<=R[i];j++){
s[i]+=a[j];
pos[j]=i;
}
}
while(m--){
opt=read();
if(opt==1){
int x,y,k;
x=read(),y=read(),k=read();
update(x,y,k);
}
else {
int x;
x=read();
write(a[x]+add[pos[x]]);
puts("");
}
}
return 0;
}
欧拉筛
#include <bits/stdc++.h>
using namespace std;
bitset<100000010> isPrime;
int Prime[6000010];
int cnt = 0;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
inline void write(int x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
write(x/10);
putchar(x%10+'0');
}
void GetPrime(int n)
{
isPrime.set();
isPrime[1] = 0;
for(int i = 2; i <= n; i++)
{
if(isPrime[i])
Prime[++cnt] = i;
for(int j = 1; j <= cnt && i*Prime[j] <= n; j++)
{
isPrime[i*Prime[j]] = 0;
if(i % Prime[j] == 0)
break;
}
}
}
void solve(){
int k;
k=read();
write(Prime[k]);
puts("");
return;
}
signed main()
{
long long n;int q;
n=read();q=read();
GetPrime(n);
while (q--)
{
solve();
}
return 0;
}
线段树模板
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define ls id<<1
#define rs id<<1|1
using namespace std;
inline int read(){//fastread
int res=0,f=1;
char ch=getchar();
while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)){ res=res*10+ch-48; ch=getchar();}
return res*f;
}
const int maxn=100000+10;
struct Node{
int L,R;
int sum,lazy,ma;
} t[maxn*4];
int n,a[maxn];
void up(int id){
t[id].sum=t[ls].sum+t[rs].sum;
t[id].ma=max(t[ls].ma,t[rs].ma);
}
void down(int id){//下传
t[ls].lazy+=t[id].lazy; t[rs].lazy+=t[id].lazy;
t[ls].sum+=(t[ls].R-t[ls].L+1)*t[id].lazy;
t[ls].ma+=t[id].lazy;
t[rs].sum+=(t[rs].R-t[rs].L+1)*t[id].lazy;
t[rs].ma+=t[id].lazy;
t[id].lazy=0;
}
void build(int id,int l,int r){//建立
t[id].L=l; t[id].R=r;
if(l==r){
t[id].sum=a[l]; t[id].ma=a[l];
return;
}
int mid=(l+r)/2;
build(ls,l,mid); //左子树
build(rs,mid+1,r);//右子树
up(id);
}
void update(int id,int l,int r,int val){//将l,r区间同时加上一个val
if(t[id].L>r || t[id].R<l) return;
if(t[id].L>=l && t[id].R<=r){//节点自己处理
t[id].lazy+=val;
t[id].sum+=(t[id].R-t[id].L+1)*val;
t[id].ma+=val;
return;
}
if(t[id].lazy!=0) down(id);
update(ls,l,r,val); update(rs,l,r,val);
up(id);
}//修改操作
int ask_sum(int id,int l,int r){//查询元素的和
if(t[id].L>r || t[id].R<l) return 0;
if(t[id].L>=l && t[id].R<=r) return t[id].sum;
if(t[id].lazy !=0) down(id);
return ask_sum(ls,l,r)+ask_sum(rs,l,r);
}
int ask_max(int id,int l,int r){//查询区间最大值
if(t[id].L>r || t[id].R<l) return -0x7f7f7f7f;
if(t[id].L>=l && t[id].R<=r) return t[id].ma;
if(t[id].lazy !=0) down(id);
return max(ask_max(ls,l,r),ask_max(rs,l,r));
}
signed main(){
int m,opt,l,r,val;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
while(m--){
cin>>opt;
if(opt==1){
cin>>l>>r>>val; update(1,l,r,val);
}
else if(opt==2){
cin>>l>>r;
cout<<ask_sum(1,l,r)<<endl;
}
}
return 0;
}
扶苏线段树模板
#include<bits/stdc++.h>
//#define int long long
//#define endl '\n'
#define ls id<<1
#define rs id<<1|1
#define getchar getchar_unlocked
#define putchar putchar_unlocked
typedef long long ll;
typedef short st;
using namespace std;
const ll maxn=1e6+10;
struct SegmentTree{
int L,R;
ll add,max,cov;
bool used;//used?
} t[maxn<<2];
int n,m;
ll a[maxn];
void up(int id){
t[id].max=max(t[ls].max,t[rs].max);
}
void down(int id){//下传
if((t[id].used)){
t[ls].cov=t[id].cov;
t[rs].cov=t[id].cov;
t[ls].add=t[id].add;
t[rs].add=t[id].add;
t[ls].max=t[id].add+t[id].cov;
t[rs].max=t[id].add+t[id].cov;
t[ls].used=1;t[rs].used=1;
}
else{//unused
t[ls].add+=t[id].add;
t[rs].add+=t[id].add;
t[ls].max+=t[id].add;
t[rs].max+=t[id].add;
}
t[id].add=t[id].cov=t[id].used=0;
}
void build(int id,int l,int r){//建立
t[id].L=l; t[id].R=r;
t[id].max=-1e18;
// t[id].add=0;
// t[id].cov=LLONG_MIN;
if(l==r){
t[id].max=a[l];
// t[id].used=0;
return;
}
int mid=(l+r)>>1;
build(ls,l,mid); //左子树
build(rs,mid+1,r);//右子树
up(id);
}
void change(int id,int l,int r,ll val){//updcov
// if(l>t[id].R || t[id].L<r) return;
if(l<=t[id].L&&t[id].R<=r){
t[id].cov=val;
t[id].add=0;
t[id].max=val;
t[id].used=1;
return;
}
/* if(t[id].add !=0)*/ down(id);
int mid=(t[id].L+t[id].R)>>1;
if(l<=mid)change(ls,l,r,val);
if(mid+1<=r)change(rs,l,r,val);
up(id);
}//覆盖操作
void update(int id,int l,int r,ll val){//updadd
// if(t[id].L>r || t[id].R<l) return;
if(t[id].L>=l && t[id].R<=r){//节点自己处理
t[id].add+=val;
t[id].max+=val;
return;
}
down(id);
int mid=(t[id].L+t[id].R)>>1;
if(l<=mid)update(ls,l,r,val);
if(mid+1<=r)update(rs,l,r,val);
up(id);
}//修改操作
ll ask_max(int id,int l,int r){//查询区间最大值
if(t[id].L>r || t[id].R<l) return -1e18;
if(l<=t[id].L&&t[id].R<=r)
return t[id].max;
/* if(t[id].add !=0)*/ down(id);
ll res=-1e18;
int mid=(t[id].L+t[id].R)>>1;
if(l<=mid)res=max(res,ask_max(ls,l,r));
if(mid+1<=r)res=max(res,ask_max(rs,l,r));
return res;
}
signed main(){
int opt;
int l,r;
ll val;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
build(1,1,n);
while(m--){
scanf("%d%d%d",&opt,&l,&r);
if(opt==1){
scanf("%lld",&val);
change(1,l,r,val);
}
else if(opt==2){
scanf("%lld",&val);
update(1,l,r,val);
}
else{
printf("%lld\n",ask_max(1,l,r));
}
}
return 0;
}
矩形周长
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define nl node_line
#define nt node_SegmentTree
#define ls id<<1
#define rs id<<1|1
#define endl '\n'
const int MAXN=1e5+10;//mod=998224353
int tot,ans,last;//last上条底的长度
int X[MAXN*2];//离散化
struct node_line{
int Lx,Rx,y;
int state;//状态
}line[MAXN*2];
struct node_SegmentTree{
int L,R,cnt,len,sum; //cnt表示当前区间被覆盖的次数,len当先扫描到的矩形的长,sum不相交包含的竖边个类
bool lcov,rcov;
} t[MAXN*4];
bool cmp(nl a,nl b){
if(a.y==b.y)return a.state>b.state;
return a.y<b.y;
}
void build(int id,int l,int r){
t[id].L=l;t[id].R=r;
if(l==r)return;
int mid=(l+r)>>1;
build(ls,l,mid);build(rs,mid+1,r);
}
void up(int id){
int l=t[id].L,r=t[id].R;
if(t[id].cnt>0){
t[id].len=X[r+1]-X[l];
t[id].lcov=t[id].rcov=1;
t[id].sum=2;
}
else{
t[id].len=t[ls].len+t[rs].len;
t[id].sum=t[ls].sum+t[rs].sum;
t[id].lcov=t[ls].lcov, t[id].rcov=t[rs].rcov;
if(t[ls].rcov&&t[rs].lcov)t[id].sum-=2;
}
}
void update(int id,int l,int r,int state){
if (l<=t[id].L && t[id].R<=r) {
t[id].cnt+=state;
up(id);
return;
}
int mid=(t[id].L+t[id].R)>>1;
if(l<=mid)update(ls,l,r,state);
if(r>mid)update(rs,l,r,state);
up(id);
}
signed main(){
last=tot=ans=0;
int n,x,y,x2,y2;
cin>>n;
for(int i=1;i<=n;i++){
cin>>x>>y>>x2>>y2;
line[i]={x,x2,y,1};
line[i+n]={x,x2,y2,-1};
X[i]=x;
X[i+n]=x2;
}
n*=2;
sort(line+1,line+n+1,cmp);
sort(X+1, X+n+1);
//去重离散化
tot=unique(X+1, X+n+1)-X-1;
build(1,1,tot);//建立线段树
for(int i=1;i<n;i++) {
int L=lower_bound(X+1,X+tot+1,line[i].Lx)-X;
int R=lower_bound(X+1,X+tot+1,line[i].Rx)-X;
update(1,L,R-1,line[i].state);
ans=ans+abs(last-t[1].len);//横边长度
last=t[1].len;
ans=ans+t[1].sum*(line[i+1].y-line[i].y);
}
ans=ans+line[n].Rx-line[n].Lx;
cout<<ans<<endl;
return 0;
}
矩形面积并
#include<bits/stdc++.h>
#define int long long
#define nl node_line
#define nt node_SegmentTree
#define ls id<<1
#define rs id<<1|1
#define endl '\n'
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
using namespace std;
const int MAXN=200000+10;
struct node_SegmentTree{
int L,R;
int cnt,len;
}t[MAXN*8];
struct node_line{
int l,r,h,state;
}a[MAXN*2];
int n,maxv=0,b[MAXN*2];
bool cmp(nl a,nl b){
return a.h<b.h;
}
void build(int id,int l,int r){
t[id].L=l;t[id].R=r;
if(t[id].L==t[id].R)return;
int mid=(l+r)>>1;
build(ls,l,mid);build(rs,mid+1,r);
}
void update(int id,int l,int r,int state){
if(t[id].L>r||t[id].R<l)return;
if(t[id].L>=l&&t[id].R<=r){
t[id].cnt+=state;
if(t[id].cnt==0){
t[id].len=t[ls].len+t[rs].len;
}
else t[id].len=b[t[id].R+1]-b[t[id].L];
return;
}
update(ls,l,r,state);update(rs,l,r,state);
if(t[id].cnt==0){
t[id].len=t[ls].len+t[rs].len;
}
else t[id].len=b[t[id].R+1]-b[t[id].L];
}
signed main(){
int x,y,x2,y2;
IOS;
cin>>n;
for(int i=1;i<=n;i++){
cin>>x>>y>>x2>>y2;
if(x>x2){swap(x,x2),swap(y,y2);}
maxv=max(maxv,x2);
a[i*2-1].h=min(y,y2);
a[i*2-1].l=x;
a[i*2-1].r=x2;
a[i*2-1].state=1;
a[i*2].h=max(y,y2);
a[i*2].l=x; a[i*2].r=x2;
a[i*2].state=-1;
b[i*2-1]=x;
b[i*2]=x2;
}
n*=2;
sort(a+1,a+n+1,cmp);
sort(b+1,b+n+1);
int tot=unique(b+1,b+n+1)-b-1;
for(int i=1;i<=n;i++){
int xl=lower_bound(b+1,b+tot+1,a[i].l)-b;
int xr=lower_bound(b+1,b+tot+1,a[i].r)-b;
a[i].l=xl; a[i].r=xr;
}
build(1,1,tot);
int now=a[1].h;
update(1,a[1].l,a[1].r-1,a[1].state);
int ans=0;
for(int i=2;i<=n;i++){
int len=t[1].len;
ans+=len*(a[i].h-now);
now=a[i].h;
update(1,a[i].l,a[i].r-1,a[i].state);
}
cout<<ans<<endl;
return 0;
}
普通平衡树(离散化权值线段树)
#include<bits/stdc++.h>
#define int long long
using namespace std;
//该题是一个权值线段树离线算法实现平衡树,如果强制在线就不行
const int maxn=100000+10;
struct node {
int l,r,cnt;//sum表示数值范围内,数字出现的总次数
} tr[maxn*4];
int a[maxn],b[maxn],n,opt[maxn],tot=0,p;
inline void build(int id,int l,int r) {
tr[id].l=l;
tr[id].r=r;
if(l==r) return;
int mid=(l+r)/2;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
}
inline void update(int id,int l,int r,int x) {
if(tr[id].l>r || tr[id].r<l) return;
if(tr[id].l>=l && tr[id].r<=r) {
tr[id].cnt+=x;
return;
}
update(id*2,l,r,x);
update(id*2+1,l,r,x);
tr[id].cnt=tr[id*2].cnt+tr[id*2+1].cnt;
}
int q_rank(int id,int l,int r) { //查询数字在l-r范围内出现的个数
if(tr[id].l>r || tr[id].r<l) return 0;
if(tr[id].l>=l && tr[id].r<=r) return tr[id].cnt;
return q_rank(id*2,l,r)+q_rank(id*2+1,l,r);
}
int q_num(int id,int x) {//查询当前线段树,出现次数为x的数
if(tr[id].l==tr[id].r) return tr[id].l;
if(x<=tr[id*2].cnt) return q_num(id*2,x);
else return q_num(id*2+1,x-tr[id*2].cnt);
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1; i<=n; i++) { //把要用到的操作和数存下来
cin>>opt[i]>>a[i];
if(opt[i]!=4) b[++tot]=a[i];
}
sort(b+1,b+tot+1);
tot=unique(b+1,b+tot+1)-b-1;//去重
build(1,1,tot);
for(int i=1; i<=n; i++) { //枚举操作
if(opt[i]!=4) p=lower_bound(b+1,b+tot+1,a[i])-b;//因为4操作不是对数值操作
if(opt[i]==1) update(1,p,p,1);//插入x
if(opt[i]==2) update(1,p,p,-1);//删除x
if(opt[i]==3) { //查询数x的排名,排名定义为比当前数小的数的个数+1
if(p==1) cout<<1<<endl;
else cout<<q_rank(1,1,p-1)+1<<endl;
}
if(opt[i]==4) { //排名为x的数,即出现的数字个数为x的数值
int k=q_num(1,a[i]);
cout<<b[k]<<endl;//注意离散化后的,所以需要还原
}
if(opt[i]==5) { //查询x的前驱
int rk=q_rank(1,1,p-1);//先找到当前小于等于p-1的个数
int k=q_num(1,rk);//再查询个数对应的数值
cout<<b[k]<<endl;
}
if(opt[i]==6) { //查询数字x的后继
int rk=q_rank(1,1,p)+1;//先找到当前小于等于p的个数+1
int k=q_num(1,rk);//再查询个数对应的数值
cout<<b[k]<<endl;
}
}
return 0;
}
普通平衡树(平衡树)
有旋Treap
#include<bits/stdc++.h>
using namespace std;
const int MAXN=2e6+10;
int root=0,k;
struct treap{
int ls,rs;
int val,pri;
int cnt,size;
}t[MAXN];
void up(int id){t[id].size=t[t[id].ls].size+t[t[id].rs].size+t[id].cnt;}
void zag(int &rt){//左旋
int b=t[rt].rs;
t[rt].rs=t[b].ls;
t[b].ls=rt;
up(rt);up(b);
rt=b;
}
void zig(int &rt){//右旋
int b=t[rt].ls;
t[rt].ls=t[b].rs;
t[b].rs=rt;
up(rt);up(b);
rt=b;
}
void insert(int &rt,int x){
if(rt==0){
t[++k].val=x;
t[k].cnt=t[k].size=1;
t[k].pri=rand()%1145140;
rt=k;
return;
}
t[rt].size++;
if(x==t[rt].val){
t[rt].cnt++;
return;
}
if(x<t[rt].val){
insert(t[rt].ls,x);
if(t[t[rt].ls].pri<t[rt].pri)zig(rt);
}
else{
insert(t[rt].rs,x);
if(t[t[rt].rs].pri<t[rt].pri)zag(rt);
}
}
void del(int &rt,int x){
if(rt==0)return;
if(t[rt].val==x){
if(t[rt].cnt>1){
t[rt].cnt--;
t[rt].size--;
return;
}
if(t[rt].ls==0||t[rt].rs==0){
rt=t[rt].ls+t[rt].rs;
}
else{
if(t[t[rt].ls].pri<t[rt].pri){
zig(rt);del(rt,x);
}
else{
zag(rt);del(rt,x);
}
}
}
else if(x<t[rt].val){
t[rt].size--;del(t[rt].ls,x);
}
else {
t[rt].size--;del(t[rt].rs,x);
}
}
int fRank(int rt,int x){
if(rt==0)return 1;
if(x==t[rt].val)return t[t[rt].ls].size+1;
if(t[rt].val<x)return t[t[rt].ls].size+t[rt].cnt+fRank(t[rt].rs,x);
else return fRank(t[rt].ls,x);
}
int fVal(int rt,int x){
if(rt==0)return 0;
if(t[t[rt].ls].size>=x)return fVal(t[rt].ls,x);
else if(t[t[rt].ls].size+t[rt].cnt<x)return fVal(t[rt].rs,x-t[t[rt].ls].size-t[rt].cnt);
else return t[rt].val;
}
const int INF=0x7f7f7f7f;
int fPre(int rt,int x){
if(rt==0)return -INF;
if(t[rt].val<x)return max(t[rt].val,fPre(t[rt].rs,x));
else return fPre(t[rt].ls,x);
}
int fNext(int rt,int x){
if(rt==0)return INF;
if(t[rt].val>x)return min(t[rt].val,fNext(t[rt].ls,x));
else return fNext(t[rt].rs,x);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
srand(time(NULL));
memset(t,0,sizeof(t));
int m,n,opt,v,xx,ans=0,last=0;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>v;
insert(root,v);
}
while(m--){
cin>>opt>>xx;
int x=xx^last;
if(opt==1)insert(root,x);
if(opt==2)del(root,x);
if(opt==3){last=fRank(root,x);ans=ans^last;}
if(opt==4){last=fVal(root,x);ans=ans^last;}
if(opt==5){last=fPre(root,x);ans=ans^last;}
if(opt==6){last=fNext(root,x);ans=ans^last;}
}
cout<<ans;
return 0;
}
FHQ Treap
#include<bits/stdc++.h>
using namespace std;
const signed int MAXN=1.1e6;
struct FHQNode{
int ls,rs;
int val,pri,size;
}t[MAXN];
int tot=0,root=0,n,m,opt,Fx,last=0,Tx;
void up(int id){t[id].size=t[t[id].ls].size+t[t[id].rs].size+1;return;}
void crt_node(int x){//新建
++tot;
t[tot].size=1;
t[tot].ls=t[tot].rs=0;
t[tot].val=x;
t[tot].pri=rand();
return;
}
void split(int u,int x,int &L,int &R){
if(u==0){L=R=0;return;}
if(t[u].val<=x){
L=u;//左边确定
split(t[u].rs,x,t[u].rs,R);
}
else{
R=u;//右边确定
split(t[u].ls,x,L,t[u].ls);
}
up(u);
return;
}
int merge(int L,int R){
if(L==0||R==0)return L+R;
if(t[L].pri>t[R].pri){
t[L].rs=merge(t[L].rs,R);
up(L);
return L;
}
else{
t[R].ls=merge(L,t[R].ls);
up(R);
return R;
}
}
int insert(int x){
int L,R;
split(root,x,L,R);
crt_node(x);
root=merge(merge(L,tot),R);
return tot;
}
int deldot(int x){//删除第一个值为x的点
int L,R,mid;
split(root,x,L,R);
split(L,x-1,L,mid);
mid=merge(t[mid].ls,t[mid].rs);
root=merge(merge(L,mid),R);
return root;
}
int delall(int x){//删除所有的值为x的点
int L,R,mid;
split(root,x,L,R);
split(L,x-1,L,mid);
root=merge(L,R);
return root;
}
int fRank(int x){
int L,R,ans;
split(root,x-1,L,R);
ans=t[L].size+1;
root=merge(L,R);
return ans;
}
int kth(int u,int k){
if(k==t[t[u].ls].size+1)return u;
if(k<=t[t[u].ls].size)return kth(t[u].ls,k);
return kth(t[u].rs,k-t[t[u].ls].size-1);
}
int fPre(int x){
int L,R,ans;
split(root,x-1,L,R);
ans=t[kth(L,t[L].size)].val;
root=merge(L,R);
return ans;
}
int fNext(int x){
int L,R,ans;
split(root,x,L,R);
ans=t[kth(R,1)].val;
root=merge(L,R);
return ans;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
int v;
cin>>v;
insert(v);
}
int ans=0;
while(m--){
cin>>opt>>Fx;
Tx=Fx^last;
if(opt==1)insert(Tx);
else if(opt==2)deldot(Tx);
else if(opt==3)last=fRank(Tx),ans^=last;
else if(opt==4)last=t[kth(root,Tx)].val,ans^=last;
else if(opt==5)last=fPre(Tx),ans^=last;
else if(opt==6)last=fNext(Tx),ans^=last;
}
cout<<ans;
return 0;
}
树链剖分/重链剖分
#include<bits/stdc++.h>
#define ls id<<1
#define rs id<<1|1
#define int long long// use long long is very important!
using namespace std;
int dep[100001],fa[100001],head[100001],siz[100001],son[100001],top[100001],tid[100001],pos[100001],tot=0,ord=0;
int a[100001];
int n,m,root,p,opt;//son:重儿子,tid和pos处理树上与链上的映射
struct edge{
int to,nxt;
}ed[100001*2];
struct SegmentTreeNode{
int L,R;
int sum,lazy;
} t[100001*4];
inline int read(){
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}//快读
inline void write(int x){
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
write(x/10);
putchar(x%10+'0');
//puts("");
}//快输
void addedge(int a,int b){
ed[++tot].to=b;
ed[tot].nxt=head[a];
head[a]=tot;
}
void dfs1(int id,int father){
dep[id]=dep[father]+1;
fa[id]=father;
siz[id]=1;
son[id]=0;
for(int i=head[id];i;i=ed[i].nxt){
int t=ed[i].to;
if(t!=father){
dfs1(t,id);
siz[id]+=siz[t];
if(siz[t]>siz[son[id]])son[id]=t;
}
}
}
void dfs2(int id,int topp){//树链剖分
top[id]=topp;
pos[id]=++ord;
tid[ord]=id;
if(!son[id])return;
dfs2(son[id],topp);
for(int i=head[id];i;i=ed[i].nxt){
int t=ed[i].to;
if(t!=son[id]&&t!=fa[id])dfs2(t,t);
}
}
void up(int id){
t[id].sum=(t[ls].sum+t[rs].sum);
}
void down(int id){//处理编号id的为标记,下传给它的儿子
if (!t[id].lazy) return;
t[ls].lazy+=t[id].lazy;
t[rs].lazy+=t[id].lazy;
t[ls].sum+=((t[ls].R-t[ls].L+1)*t[id].lazy);
t[rs].sum+=((t[rs].R-t[rs].L+1)*t[id].lazy);
t[id].lazy=0;
}
void build(int id,int l,int r){
t[id].L=l,t[id].R=r;
t[id].lazy=0;t[id].sum=0;
if(l==r){t[id].sum=a[tid[l]];return;}
int mid=(l+r)>>1;
build(ls,l,mid);build(rs,mid+1,r);
up(id);
}
void update(int id,int l,int r,int val){//将l,r区间同时加上一个val
if(t[id].L>r || t[id].R<l) return;
if(t[id].L>=l && t[id].R<=r){//节点自己处理
t[id].lazy+=val;
t[id].sum+=(t[id].R-t[id].L+1)*val;
return;
}
if(t[id].lazy!=0) down(id);
int mid=(t[id].L+t[id].R)>>1;
if(l<=mid)update(ls,l,r,val);
if(r>mid)update(rs,l,r,val);
up(id);
}
int ask_sum(int id,int l,int r){
if(t[id].L>r || t[id].R<l) return 0;
if(t[id].L>=l && t[id].R<=r) return t[id].sum;
if(t[id].lazy !=0) down(id);
return (ask_sum(ls,l,r)+ask_sum(rs,l,r));
}
void tree_update(int u,int v,int val){//树上更新
//不同重链
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);//先从top的depth深的那条重链开始
update(1,pos[top[u]],pos[u],val);
u=fa[top[u]];//轻边
}
//同一重链
if(dep[u]>dep[v])swap(u,v);
update(1,pos[u],pos[v],val);
}
void subtree_update(int id,int val){//子树树上更新
update(1,pos[id],pos[id]+siz[id]-1,val);
}
void node_update(int id,int x, int val) {
if (t[id].L==t[id].R) {
t[id].sum+=val;
return;
}
down(id);
int mid = (t[id].L+t[id].R)>>1;
if (x<=mid)node_update(ls,x,val);
else node_update(rs,x,val);
up(id);
}
int tree_sum(int u,int v){
int sum=0;
//不同重链
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);//先从top的depth深的那条重链开始
sum+=ask_sum(1,pos[top[u]],pos[u]);
u=fa[top[u]];//轻边
}
//同一重链
if(dep[u]>dep[v])swap(u,v);
sum+=ask_sum(1,pos[u],pos[v]);
return sum;
}
int subtree_sum(int id){
return ask_sum(1,pos[id],pos[id]+siz[id]-1);
}
signed main(){
//ios::sync_with_stdio(0);
//cin.tie(0);
//cout.tie(0);
memset(head,0,sizeof(head));
n=read();m=read();
root=1;p=2147483647;
for(int i=1;i<=n;i++){
a[i]=read();
}
for(int i=1;i<n;i++){
int x,y;
x=read();y=read();
addedge(x,y);addedge(y,x);
}
dfs1(root,0);
dfs2(root,root);
build(1,1,n);
while(m--){
opt=read();
return 0;
}
点分治
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int N=1e5+50;
struct ed{
int v,w;
};
vector<ed>e[N];
int root,dep[N],f[N],siz[N],n,k,m,que[N],S,tot,len[N];
bool vis[N],ans[10000001];
void getroot(int u,int fa){
f[u]=0,siz[u]=1;
for(auto x:e[u]){
int v=x.v;
if(vis[v]||v==fa)continue;
getroot(v,u);
siz[u]+=siz[v];
f[u]=max(f[u],siz[v]);
}
f[u]=max(f[u],S-siz[u]);
if(f[u]<f[root])root=u;
}
void getdep(int u,int fa){
for(auto x:e[u]){
int v=x.v,w=x.w;
if(v==fa||vis[v])continue;
dep[v]=dep[u]+w;
len[++tot]=dep[v];
if(len[tot]<=10000000)ans[len[tot]]=1;
getdep(v,u);
}
}
void getans(int u){
vector<int> total;
total.push_back(0);
for(auto x:e[u]){
int v=x.v,w=x.w;
if(vis[v])continue;
tot=0;
dep[v]=w;
len[++tot]=w;
if(w<=10000000)ans[w]=1;
getdep(v,u);
for(int i=1;i<=tot;i++){
for(int d:total){
int sum=len[i]+d;
if(sum<=10000000)ans[sum]=1;
}
}
for(int i=1;i<=tot;i++)total.push_back(len[i]);
}
}
void sol(int u){
vis[u]=1;
getans(u);
for(auto x:e[u]){
int v=x.v;
if(vis[v])continue;
S=siz[v];
root=0,f[root]=N;
getroot(v,0);
sol(root);
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1,cu,cv,cw;i<n;i++){
scanf("%d%d%d",&cu,&cv,&cw);
e[cu].push_back({cv,cw});
e[cv].push_back({cu,cw});
}
for(int i=1;i<=m;i++)scanf("%d",&que[i]);
S=n,f[0]=N,root=0;
getroot(1,0);
sol(root);
for(int i=1;i<=m;i++)puts(ans[que[i]]?"AYE":"NAY");
}
缩点
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100050;
int a[maxn],dfn[maxn],low[maxn],instack[maxn],ord=0,color[maxn],sum[maxn],color_cnt=0,rudu[maxn],dis[maxn],n,m,ans=0;
//color:强连通编号 sum:强连通权值和 color_cnt:强连通个数
vector<int> G[maxn],G2[maxn];
stack<int> stk;
void tarjan(int u){
dfn[u]=low[u]=++ord;
stk.push(u);
instack[u]=1;
for(int v:G[u]){
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(instack[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u]){
color_cnt++;
while(true){
int v=stk.top();
color[v]=color_cnt;
instack[v]=0;
sum[color_cnt]+=a[v];
stk.pop();
if(u==v)break;
}
}
}
void tp(){//拓扑
queue<int>q;
for(int i=1;i<=color_cnt;i++){
if(!rudu[i]){
q.push(i);
dis[i]=sum[i];
}
}
while(!q.empty()){
int u=q.front();
q.pop();
for(int i:G2[u]){
dis[i]=max(dis[i],dis[u]+sum[i]);
if(--rudu[i]==0)q.push(i);
}
}
for(int i=1;i<=n;i++){
ans=max(ans,dis[i]);
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=m;i++){
int u,v;
cin>>u>>v;
G[u].push_back(v);
}
for(int i=1;i<=n;i++){
if(!dfn[i])tarjan(i);
}
for(int u=1;u<=n;u++){
int uu=color[u];
for(int v:G[u]){
int vv=color[v];
if(uu!=vv){
G2[uu].push_back(vv);
rudu[vv]++;
}
}
}
tp();
cout<<ans;
return 0;
}
字典树
#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
struct cnt_trie{
vector<vector<int>>ch;
vector<int>cnt;
int ct=0;
int gn_map[128];
//如果用全局数组,不用vector,常数约为1/2
void clear(){
ch.clear();
cnt.clear();
ch.push_back(vector<int>(65, 0)); // 初始化根节点
cnt.push_back(0);
ct=0;
}
cnt_trie(){cnt_trie::init_gn();clear();}
void init_gn() {
for(int i=0;i<128;i++) gn_map[i]=-1;
for(char c='A';c<='Z';c++) gn_map[c]=c-'A';
for(char c='a';c<='z';c++) gn_map[c]=c-'a'+26;
for(char c='0';c<='9';c++) gn_map[c]=c-'0'+52;
}
inline int gn(char x){return gn_map[(int)x];}
void insert(string str){
int p=0,l=str.size();
for(int i=0;i<l;i++){
int c=gn(str[i]);
if(!ch[p][c]){
ch.push_back(vector<int>(65, 0));//全局数组就不用这两个push_back,直接用
cnt.push_back(0);
ch[p][c]=++ct;
}
p=ch[p][c];
cnt[p]++;
}
}
int find_cnt(string str){
int p=0,l=str.size();
for(int i=0;i<l;i++){
int c=gn(str[i]);
if(!ch[p][c]) return 0;
p=ch[p][c];
}
return cnt[p];
}
pair<int,int> find_range(string str){
int p=0,l=str.size();
for(int i=0;i<l;i++){
int c=gn(str[i]);
if(!ch[p][c]) return {0,0};
p=ch[p][c];
}
return {p,ct};
}
};
int main(){
int T;
cin>>T;
cnt_trie tri;
while(T--){
tri.clear();
int n,q;
cin>>n>>q;
while(n--){
string s;
cin>>s;
tri.insert(s);
}
while(q--){
string qr;
cin>>qr;
cout<<tri.find_cnt(qr)<<endl;
}
}
return 0;
}
文艺平衡树
#include<bits/stdc++.h>
using namespace std;
const int maxn=2*114514;
struct FHQNode{
int ls,rs;
int val,pri,size;
int lazy;
}t[maxn];
int tot=0,root=0,n,m;
void crt_node(int x){
++tot;
t[tot].size=1;
t[tot].lazy=t[tot].ls=t[tot].rs=0;
t[tot].val=x;
t[tot].pri=rand();
return;
}
void up(int id){
t[id].size=t[t[id].ls].size+t[t[id].rs].size+1;
}
void down(int id){
if(t[id].lazy){
swap(t[id].ls,t[id].rs);
t[t[id].ls].lazy^=1;
t[t[id].rs].lazy^=1;
t[id].lazy=0;
}
}
void split(int id,int x,int &L,int &R){
if(id==0){L=R=0;return;}
down(id);
if(t[t[id].ls].size+1<=x){
L=id;
split(t[id].rs,x-t[t[id].ls].size-1,t[id].rs,R);
}
else {
R=id;
split(t[id].ls,x,L,t[id].ls);
}
up(id);
return;
}
int merge(int L,int R){
if(L==0||R==0)return L+R;
if(t[L].pri>t[R].pri){
down(L);
t[L].rs=merge(t[L].rs,R);
up(L);
return L;
}
else{
down(R);
t[R].ls=merge(L,t[R].ls);
up(R);
return R;
}
}
void print(int id){
if(id==0)return;
down(id);
print(t[id].ls);
printf("%d ",t[id].val);
print(t[id].rs);//中序遍历
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
crt_node(i);
root=merge(root,tot);
}
while(m--){
int l,r,L,R,mid;
cin>>l>>r;
split(root,r,L,R);
split(L,l-1,L,mid);
t[mid].lazy^=1;
root=merge(merge(L,mid),R);
}
print(root);
return 0;
}
网络流
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=205,M=5005,inf=2147483647;
int n,m,s,t;
int dis[N];
struct edge{
int l,r,c;
int nxt;
}ed[M*2];
int head[N],cnt=2;
void adde(int l,int r,int c){
ed[cnt].l=l;
ed[cnt].r=r;
ed[cnt].c=c;
ed[cnt].nxt=head[l];
head[l]=cnt;
cnt++;
}
bool bfs(){
queue<int> q;
for(int i=1;i<=n;i++) dis[i]=-1;
dis[s]=0;
q.push(s);
while(!q.empty()){
int curr=q.front();
q.pop();
for(int i=head[curr];i;i=ed[i].nxt){
if(dis[ed[i].r]==-1&&ed[i].c>0){
dis[ed[i].r]=dis[curr]+1;
q.push(ed[i].r);
if(ed[i].r==t)return 1;
}
}
}
return(dis[t]!=-1);
}
int dfs(int start,int flow){
int cnt=0;
if(start==t) return flow;
for(int i=head[start];i&&flow;i=ed[i].nxt){
if((ed[i].c>0)&&(dis[ed[i].r]==dis[start]+1)){
int ret=dfs(ed[i].r,min(flow,ed[i].c));
if(ret==0)dis[ed[i].r]=inf;
if(ret>0){
ed[i].c-=ret;
ed[i^1].c+=ret;
cnt+=ret;
flow-=ret;
}
}
}
return cnt;
}
void dinic(){
int ans=0;
while(bfs()){
ans+=dfs(s,inf);
}
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin>>n>>m>>s>>t;
for(int i=0;i<m;i++){
int u,v,w;
cin>>u>>v>>w;
adde(u,v,w);
adde(v,u,0);
}
dinic();
return 0;
}
二分图
#include<bits/stdc++.h>
using namespace std;
const int maxn=1000005;
vector<int> G[maxn];
int match[maxn],ans=0;
bool matched[maxn];
bool find(int u){
for(int v:G[u]){
if(!matched[v]){
matched[v]=1;
if(!match[v]||find(match[v])){
match[v]=u;
return true;
}
}
}
return false;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,m,e;
cin>>n>>m>>e;
for(int i=0;i<e;i++){
int u,v;
cin>>u>>v;
G[u].push_back(v);
}
for(int i=1;i<=n;i++){
memset(matched,0,sizeof(matched));
if(find(i))ans++;
}
cout<<ans;
return 0;
}
Dijkstra
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1100010,inf=0x7fffffff;
struct edge{
int to,w;
};
vector<edge> G[maxn];
struct qnode{
int id,val;
qnode(int d,int v){id=d; val=v;}
bool friend operator<(qnode n1,qnode n2)
{
return n1.val>n2.val;
}
};
int dis[maxn],n,m,s;
bool vis[maxn];
priority_queue<qnode> q;
void dijkstra(){
for(int i=1;i<=n;i++)dis[i]=inf;
memset(vis,0,sizeof(vis));
dis[s]=0;
q.push(qnode(s,0));
while(!q.empty()){
qnode qnd=q.top();q.pop();
int u=qnd.id;
if(vis[u])continue;
vis[u]=1;
for(int i=0;i<G[u].size();i++){
int v=G[u][i].to,w=G[u][i].w;
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
q.push(qnode(v,dis[v]));//松弛
}
}
}
}
signed main(){
cin>>n>>m>>s;
for(int i=1;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
G[u].push_back({v,w});
}
dijkstra();
for(int i=1;i<=n;i++){
if(dis[i]==inf) cout<<(1<<31)-1<<' ';
else cout<<dis[i]<<' ';
}
return 0;
}
可持久化线段树1
//“你说得对,但是主席树十分持♂久♂,因为它可→持↑久↓化→”
#include<bits/stdc++.h>
using namespace std;
const int MAXN=3e7+100;
int cnt=1,a[MAXN],n,m,roots[MAXN];
struct Tree{
int L,R,val;
}t[MAXN*4];
inline int read(){int x=0,f=1;char ch=getchar();while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}while (ch>='0'&&ch<='9'){x=(x << 1) + (x << 3)+ch-48;ch=getchar();}return x*f;}//快读
inline void write(int x){if(x<0){putchar('-');x=-x;}if(x>9)write(x/10);putchar(x%10+'0');}//快输
int crt_node(int id){
cnt++;
t[cnt]=t[id];
return cnt;
}
int build(int id,int l,int r){
id=++cnt;
if(l==r){
t[id].val=a[l];
return cnt;
}
int mid=(l+r)>>1;
t[id].L=build(t[id].L,l,mid);
t[id].R=build(t[id].R,mid+1,r);
return id;
}
int update(int id,int l,int r,int x,int val){
id=crt_node(id);
if(l==r)t[id].val=val;
else{
int mid=(l+r)>>1;
if(x<=mid)t[id].L=update(t[id].L,l,mid,x,val);
else t[id].R=update(t[id].R,mid+1,r,x,val);
}
return id;
}
int ask(int id,int l,int r,int x){
if(l==r)return t[id].val;//单点
int mid=(l+r)>>1;
if(x<=mid)return ask(t[id].L,l,mid,x);//在左
else return ask(t[id].R,mid+1,r,x);//在右
}
int main(){
int v,loc,val;
int opt;
n=read();m=read();
for(int i=1;i<=n;i++)a[i]=read();
roots[0]=build(0,1,n);
for(int i=1;i<=m;i++){
v=read();opt=read();loc=read();
if(opt==1){
val=read();
roots[i]=update(roots[v],1,n,loc,val);
}
else{
write(ask(roots[v],1,n,loc)),puts("");
roots[i]=roots[v];
}
}
return 0;
}