标签:算法 loop prim 中国剩余定理 else mod long use UI
KMP
void getnext(){
int q, k;
next1[0] = 0;
for(q = 1, k = 0; q < m; q++){
while(k > 0 && sh[q] != sh[k])
k = next1[k-1];
if(sh[q] == sh[k])
k++;
next1[q] = k;
}
}
int kmp(){
int i, q;
int ans = 0;
for(i = 0, q = 0; i < n; i++){
while(q > 0 && sh[q] != ch[i])
q = next1[q-1];
if(sh[q] == ch[i])
q++;
if(q == m)
ans++;
}
return ans;
}
字典树
typedef struct Trie{
Trie *next[MAX];
int v;
}Trie;
Trie *root;
void createTrie(char *str){
int len = strlen(str);
Trie *p = root, *q;
for(int i = 0; i < len; i++){
int id = str[i] - ‘0‘;
if(p->next[id] == NULL){
q =(Trie *)malloc(sizeof(Trie));
q->v = 1;
for(int j = 0; j < MAX; j++){
q->next[j] = NULL;
}
p->next[id] = q;
p = p->next[id];
}
else{
p->next[id]->v++;
p = p->next[id];
}
}
p->v = -1;
}
int findTrie(char *str){
int len = strlen(str);
Trie *p = root;
for(int i = 0; i < len; i++){
int id = str[i] -‘0‘;
p = p->next[id];
if(p == NULL)
return 0;
if(p->v == -1)
return -1;
}
return -1;
}
void delete_(Trie *g){
if(g==NULL)
return;
for(int i = 0; i < MAX; i++){
if(g->next[i] != NULL)
delete_(g->next[i]);
}
free(g);
return;
}
AC自动机
struct node{
node *next[26];
node *fail;
int sum;
}*root, *q[10000000]
void createTrie(char *str){
node *p = root, *q;
int len = strlen(str);
for(int i = 0; i < len; i++){
int id = str[i] - ‘a‘;
if(p->next[id] == NULL){
q = (struct node *)malloc(sizeof(struct node));
for(int j = 0; j < 26; j++)
q->next[j] = 0;
q->sum = 0;
q->fail = 0;
p->next[id] = q;
}
p = p->next[id];
}
p->sum++;
}
void build_fail_pointer(){
head = 0,tail = 1;
q[head] = root;
node *p, *temp;
while(head<tail){
temp = q[head++];
for(int i = 0; i < 26; i++){
if(temp->next[i]){
if(temp == root)
temp->next[i]->fail = root;
else{
p = temp->fail;
while(p){
if(p->next[i]){
temp->next[i]->fail = p->next[i];
break;
}
p = p->fail;
}
if(p == NULL)
temp->next[i]->fail = root;
}
q[tail++] = temp->next[i];
}
}
}
}
void ac_automation(char *str){
node *p = root;
int len = strlen(str);
for(int i = 0; i < len; i++){
int id = str[i] - ‘a‘;
while(!p->next[id] && p != root)
p = p->fail;
p = p->next[id];
if(!p)
p = root;
node *temp = p;
while(temp != root){
if(temp->sum >= 0){
cnt += temp->sum;
temp->sum = -1;
}
else break;
temp = temp->fail;
}
}
}
主席树
void Build(int& o, int l, int r){
o = ++ tot;
sum[o] = 0;
if(l == r) return;
int m = (l + r) >> 1;
Build(ls[o], l, m);
Build(rs[o], m + 1, r);
}
void update(int& o, int l, int r, int last, int p){
o = + +tot;
ls[o] = ls[last];
rs[o] = rs[last];
sum[o] = sum[last] + 1;
if(l == r) return;
int m = (l + r) >> 1;
if(p <= m) update(ls[o], l, m, ls[last], p);
else update(rs[o], m + 1, r, rs[last], p);
}
int query(int ss, int tt, int l, int r, int k){
if(l == r) return l;
int m = (l + r) >> 1;
int cnt = sum[ls[tt]] - sum[ls[ss]];
if(k <= cnt) return query(ls[ss], ls[tt], l, m, k);
else return query(rs[ss], rs[tt], m + 1, r, k - cnt);
}
int main(){
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &q);
for(int i = 1; i <= n; i ++) scanf("%d", a + i), b[i] = a[i];
sort(b + 1, b + n + 1);
sz = unique(b + 1, b + n + 1) - (b + 1);
tot = 0;
Build(rt[0],1, sz);
//for(int i = 0; i <= 4 * n; i ++)
//printf("%d,rt = %d,ls = %d, rs = %d, sum = %d\n", i, rt[i], ls[i], rs[i], sum[i]);
for(int i = 1; i <= n; i ++)
a[i] = lower_bound(b + 1, b + sz + 1, a[i]) - b;
for(int i = 1; i <= n; i ++)
update(rt[i], 1, sz, rt[i - 1], a[i]);
//for(int i = 0; i <= 5 * n; i++)
//printf("%d,rt = %d, ls = %d, rs = %d, sum = %d\n", i, rt[i], ls[i], rs[i], sum[i]);
while(q --)work();
}
return 0;
}
SA
int A[MAX_N];
int rev[MAX_N*2], sa[MAX_N *2];
int n,k;
int rank1[MAX_N], tmp[MAX_N];
bool compare_sa(int i, int j){
if(rank1[i] != rank1[j])
return rank1[i] < rank1[j];
int ri = i + k <= n ? rank1[i+k] : -1;
int rj = j + k <= n ? rank1[j+k] : -1;
return ri < rj;
}
void construct_sa(int sh[],int n,int *sa){
for(int i = 0; i <= n; i++){
sa[i] = i;
rank1[i] = i < n ? sh[i] : -1;
}
for(k = 1; k <= n; k *= 2){
sort(sa, sa + n + 1, compare_sa);
tmp[sa[0]] = 0;
for( int i = 1; i <= n; i++){
tmp[sa[i]] = tmp[sa[i-1]] + (compare_sa(sa[i-1], sa[i])? 1 : 0);
}
for(int i = 0; i <= n; i++){
rank1[i] = tmp[i];
}
}
}
void solve(){
reverse_copy(A, A+n, rev);
construct_sa(rev, n, sa);
int p1;
for(int i = 0; i < n; i++){
p1 = n - sa[i];
if(p1 >= 1 && n - p1 >=2)
break;
}
int m = n-p1;
reverse_copy(A+p1, A+n, rev);
reverse_copy(A+p1, A+n, rev+m);
construct_sa(rev, m*2, sa);
int p2;
for(int i = 0; i <= 2*n; i++){
p2 = p1 + m -sa[i];
if(p2 - p1 >= 1 && n - p2 >= 1)
break;
}
reverse(A, A+p1);
reverse(A+p1, A+p2);
reverse(A+p2, A+n);
for(int i = 0; i < n; i++)
printf("%d\n", A[i]);
}
SA—LCP
void construct_lcp(string S, int *sa, int *lcp){
for(int i = 0; i <= n; i++)
rank1[sa[i]] = i;
int h = 0;
lcp[0] = 0;
for(int i = 0; i < n; i++){
int j = sa[rank1[i] - 1];
if(h > 0) h--;
for(; j + h < n && i + h < n; h++)
if(S[j+h] != S[i+h])
break;
lcp[rank1[i]-1] = h;
}
}
中国剩余定理
ll China(ll *m,ll *a)
{
ll M=1,d,y,x=0;
for(int i=0;i<n;i++)
M*=m[i];
for(int i=0;i<n;i++){
ll w=M/m[i];
gcd(m[i],w,d,d,y);
x=(x+y*w*a[i])%M;
}
return (x+M)%M;
}
扩展欧几里得算法
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y)
{
if(b==0){
d=a;
x=1,y=0;
}
else{
gcd(b,a%b,d,y,x);
y-=(a/b)*x;
}
}
最短路
struct edge{int from, to, cost};
void shortpath(int s){
for(int i = 0; i < V; i++) d[i] = INF;
d[s] = 0;
while(1){
bool update = false;
for(int i = 0; i < E; i++){
edge e = es[i];
if(d[e.from] != INF && d[e.to] > d[e.from] + e.cost){
d[e.to] = d[e.from] + e.cost;
update = true;
}
}
if(!update) break;
}
}
bool find_negative_loop(){
memset(d,0,sizeof(d));
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m+w+m; j++)
{
edge e = ed[j];
if(d[e.to] > d[e.from] + e.cost)
{
d[e.to] = d[e.from] + e.cost;
if(i == n-1)
return true;
}
}
}
return false;
}
void floyd(int m){//}O(m^3)
for(int i = 0; i < m; i++)
for(int k = 0; k < m; k++)
for(int j = 0; j < m; j++)
d[k][j] = min(d[k][j], d[k][i] + d[i][j]);
}
struct edge{
int to,cost;
edge(){}
edge(int to, int cost) : to(to), cost(cost){}
};
vector<edge> g[Max];
typedef pair<int, int> P;
void dijkstra(int s){
priority_queue<P, vector<P>, greater<P> > que;
memset(d[s], 0x3f3f, Max * sizeof(int));
d[s][s] = 0;
que.push(P(0, s));
while(que.size())
{
P p = que.top(); que.pop();
int v = p.second;
if(d[s][v] < p.first) continue;
for(int i = 0; i < g[v].size(); i++)
{
edge e = g[v][i];
if(d[s][e.to] > d[s][v] + e.cost)
{
d[s][e.to] = d[s][v] + e.cost;
que.push(P(d[s][e.to], e.to));
}
}
}
return ;
}
生成树
struct edge{
int x, y, d;
const bool operator < (const edge& o) const { return d < o.d; }
}zhen[500002];
void initialize(){
for(int i = 1; i < N; i++) par[i] = i, _rank[i] = 0;
}
int find(int x){
if(x == par[x]) return x;
return par[x] = find(par[x]);
}
void unit(int x, int y){
int xx = find(x), yy = find(y);
if(xx == yy) return;
if(_rank[xx] < _rank[yy]) par[xx] = yy;
else
par[yy] = xx;
if(_rank[xx] == _rank[yy]) _rank[x]++;
}
bool is_thesame(int x, int y){ return find(x) == find(y); }
void kruskal(){
sort(ch, ch + E, cmp);
for(int i = 0; i < E; i++)
if(isthesame(ch[i].x, n + ch[i].y))
ans += ch[i].cost;
}
Int d[maxn][maxn], mincost[maxn];
bool used[maxn];
int prim(){
for(int i = 0; i < 102; i++)
{
mincost[i] = INF;
used[i] = false;
}
mincost[0] = 0;
int ans = 0;
while(true)
{
int flag = -1;
for(int i = 0; i < n; i++)
if(!used[i] && (flag == -1 || mincost[i]< mincost[flag]))
flag = i;
if(flag == -1)
break;
used[flag] = true;
ans += mincost[flag];
for(int i = 0; i < n; i++)
mincost[i] = min(mincost[i], d[flag][i]);
}
return ans;
}
快速幂
ll mod_pow(ll x, ll n, ll mod){
ll res = 1;
while(n>0){
if(n&1) res = res * x % mod;
x = x * x % mod;
n >>= 1;
}
return res;
}
尺取
int res = n+1;
int s = 0, t = 0, sum = 0;
while(1){
while(t<n && sum < S){//长度最短为S
sum+=a[t++];
}
if(sum < S) break;
res = min(res, t-s);
sum -= a[s++];
}
if(res > n)
res = 0;
线段树
long long ch[100010];
long long sum;
long long Stree[100010<<2],lazy[100010<<2];
void build(int root, int l, int r){
lazy[root] = 0;
if(l == r)
Stree[root] = ch[l];
else{
int mid = (l+r)/2;
build(root*2, l, mid);
build(root*2+1, mid + 1, r);
Stree[root] = Stree[root*2] + Stree[root*2+1];
}
}
void pushdown(int root,int num){
if(lazy[root]){
Stree[root*2] += 1LL*(num-(num>>1))*lazy[root];
Stree[root*2+1] += 1LL*(num>>1)*lazy[root];
lazy[root*2] += lazy[root];
lazy[root*2+1] += lazy[root];
lazy[root] = 0;
}
}
void add(int root, int L, int R, int l, int r, long long ad){
if(L>r || R < l) return;
if(R<=r && L>=l){
Stree[root] += 1LL*(R-L+1)*ad;
lazy[root] += ad;
return ;
}
pushdown(root,R-L+1);
int mid = (L+R) >> 1;
add(root*2, L, mid, l, r, ad);
add(root*2+1, mid+1, R, l, r, ad);
Stree[root] = Stree[root*2] + Stree[root*2+1];
}
void query(int root, int L, int R, int l, int r){
if(L>r || R < l) return;
if(l <= L && R <= r){
sum += Stree[root];
return ;
}
pushdown(root,R-L+1);
int mid = (L+R) >> 1;
query(root*2, L, mid, l, r);
query(root*2+1, mid+1, R, l, r);
}
BIT_Tree
int lowbit(int i)
{
return i&(-i);
}
void update(int i, int val)
{
while(i <= n)
{
a[i] += val;
i += lowbit(i);
}
}
int sum(int i)
{
int sum = 0;
while(i > 0)
{
sum += a[i];
i -= lowbit(i);
}
return sum;
}
标签:算法 loop prim 中国剩余定理 else mod long use UI
原文地址:http://www.cnblogs.com/tony-/p/7846722.html