ソート
sort(a.begin(), a.end(), greater<int>()) ;
AhoCorasick
const int D=27;
struct AHO{
vvi next;
vvi hit;
AHO(vvi pat){
next.pb(vi(D,-1));
hit.pb(vi());
REP(ip,pat.size()){
int st=0;
REP(i,pat[ip].size()){
int c=pat[ip][i];
if(next[st][c]==-1){
next[st][c]=next.size();
next.pb(vi(D,-1));
hit.pb(vi());
}
st=next[st][c];
if(i==pat[ip].size()-1) hit[st].pb(ip);
}
}
vi failuer;
failuer.resize(next.size());
queue<int> P;
REP(c,D) if(next[0][c]!=-1) P.push(next[0][c]) ;
REP(c,D) if(next[0][c]==-1) next[0][c]=0;
while(!P.empty()){
int st=P.front(); P.pop();
REP(i,hit[failuer[st]].size()){
hit[st].pb(hit[failuer[st]][i]);
}
REP(c,D){
int nst=next[st][c];
if(nst==-1 || nst==0)continue;
failuer[nst]=next[failuer[st]][c];
P.push(nst);
}
REP(c,D){
if(next[st][c]==-1)next[st][c]=next[failuer[st]][c];
}
}
}
};
文字列
vector<int> vectorFromString(string s){
istringstream iss(s);
vector<int> ret;
int n;
while(!iss.eof()){
iss >> n;
ret.push_back(n);
}
return ret;
}
string concantenate(vector<string> s){
string ret;
for(int i=0;i<s.size();i++){
for(int j=0;j<s[i].size();j++){
ret.pb(s[i][j]);
}
}
return ret;
}
数学
ll extgcd(ll a, ll b, ll &x, ll &y){
ll d=a;
if(b!=0){
d=extgcd(b, a%b, y, x);
y-=(a/b)*x;
}
else{
x=1,y=0;
}
return d;
}
ll modinverse(ll a, ll b){
ll x,y;
extgcd(a,b, x, y);
return (x%b+b)%b;
}
struct modular{
ll value;
modular(){
value=0;
}
modular(ll v){
value=(v%mod+mod)%mod;
}
modular operator+(const modular b){
return modular(value+b.value);
}
modular operator-(const modular b){
return modular( value-b.value );
}
modular operator*(const modular b){
return modular( value*b.value );
}
modular operator/(const modular b){
return modular( value*modinverse(b.value, mod) );
}
};
modular operator+(ll a, modular b){
return modular(a)+b;
}
modular operator-(ll a, modular b){
return modular(a)-b;
}
modular operator*(ll a, modular b){
return modular(a)*b;
}
modular operator/(ll a, modular b){
return modular(a)/b;
}
modular powm(moaular a, ll n){
if(n==0)return a;
if(n%2)return a*powm(a*a,n/2);
return powm(a*a,n/2);
}
int sum(vector<int>& seq){
int ret=0;
REP(i, seq.size())ret+=seq[i];
return ret;
}
ll truemod(ll n, ll m){
return (n%m+m)%m;
}
ll fact(int n){
if(n==0)return 1;
else return n*fact(n-1);
}
ll comb(vi xn){
int k=0;
REP(i,xn.size())k+=xn[i];
ll x=fact(k);
ll y=1;
REP(i,xn.size())y*=fact(xn[i]);
return x/y;
}
vvi factor;
void seive(int n){
factor.resize(n);
FOR(p,2,n){
if(factor[p].size()==0){
for(int k=p;k<n;k+=p){
int m=k;
while(m%p==0){
factor[k].pb(p);
m/=p;
}
}
}
}
}
int isprime[8000];
vi make_primelist(int upto){
REP(i, upto){
isprime[i]=1;
}
FOR(p,2,upto){
if(p*p>upto)break;
if(isprime[p]==0)continue;
int k=p+p;
while(k<upto){
isprime[k]=0;
k+=p;
}
}
vi ret;
FOR(i,2,upto){
if(isprime[i]==1)ret.push_back(i);
}
return ret;
}
comb([2,3,4])=(2+3+4)!/(2!3!4!)
vvl mul(vvl a, vvl b){
int n1=a.size(), n2=b.size(), n3=b[0].size();
vvl ret;
ret.resize(n1);
REP(i,n1)ret[i].resize(n3);
REP(i,n1) REP(j,n3) REP(k,n2) ret[i][j]=(ret[i][j]+a[i][k]*b[k][j])%mod;
return ret;
}
vvl powm(vvl s, vvl t, ll n){
if(n==0)return t;
if(n%2==0)return powm(mul(s,s), t, n/2);
else return powm(mul(s,s), mul(s,t), n/2);
}
ll det(vvl x){
ll h=1;
int n=x.size();
REP(i,n) REP(j,n) x[i][j]=truemod(x[i][j],mod);
REP(i,n){
FOR(j,i,n){
if(x[j][i]!=0 && j!=i){
REP(k,n)swap(x[j][k], x[i][k]);
h*=-1;
break;
}
}
if(x[i][i]==0)return 0;
ll v=modinverse(x[i][i], mod);
h=truemod(h*x[i][i],mod);
FOR(j,i+1,n){
ll v2=v*x[j][i]%mod;
REP(k,n) x[j][k]=truemod(x[j][k]-x[i][k]*v2,mod);
}
}
return h;
}
ll CRTsolve(vl as, vl ns){
ll N=1;
REP(i,ns.size())N*=ns[i];
ll ret=0;
debug(N);
REP(i,ns.size()){
ll r,s;
extgcd(ns[i], N/ns[i], r, s);
ret+=as[i]*(N/ns[i])%N*s%N;
ret%=N;
}
return (N+ret%N)%N;
}
フーリエ変換
const double pi=4.0*atan(1.0);
typedef complex<double> Complex;
const Complex I(0,1);
void fft_2(int delta,vector<Complex> &a){
int n=a.size();
double theta=delta*2*pi/n;
for (int m = n; m >= 2; m >>= 1) {
int mh = m >> 1;
for (int i = 0; i < mh; i++) {
Complex w = exp(i*theta*I);
for (int j = i; j < n; j += m) {
int k = j + mh;
Complex x = a[j] - a[k];
a[j] += a[k];
a[k] = w * x;
}
}
theta *= 2;
}
int i = 0;
for (int j = 1; j < n - 1; j++) {
for (int k = n >> 1; k > (i ^= k); k >>= 1);
if (j < i) swap(a[i], a[j]);
}
}
vector<Complex> pr(const vector<Complex> &a, const vector<Complex> &b){
assert(a.size()==b.size());
vector<Complex> ret(a.size());
REP(i,ret.size()){
ret[i]=a[i]*b[i];
}
return ret;
}
//bluestein's FFT
vector<Complex> fft(const vector<Complex> &x){
int n=x.size();
int m=1;
while(m<2*n)m*=2;
vector<Complex> a(m),b(m);
for(ll i=0; i<n; i++){
a[i]=( x[i]*exp(-pi*i*i/n*I) );
b[i]=( exp(pi*i*i/n*I ) );
if(i!=0)b[m-i]=b[i];
}
fft_2(1, a);
fft_2(1, b);
vector<Complex> c=pr(a,b);
fft_2(-1,c);
assert(c.size()==m);
REP(i,c.size())c[i]/=m;
assert(c.size()>=n);
vector<Complex> ret(n);
REP(i,n){
ret[i]=c[i]*exp(-pi*i*i/n*I );
}
return ret;
}
//最大流を求める。頂点の個数の上限をMAX_Vにセットしておく。
//add_edge(A,B,C)でAからBへ容量Cの元辺を追加する。
// max_flow(s,t)でsからtへの最大流量を求める。
const int MAX_V=5010;
ll INF=1LL<<62-1;
struct edge{
int to;
ll cap;
int rev;
};
struct cal_max_flow{
vector<edge> G[MAX_V];
int level[MAX_V];
int iter[MAX_V];
void add_edge(int from,int to,ll cap){
G[from].pb((edge){to,cap,G[to].size()});
G[to].pb((edge){from,0,G[from].size()-1});
}
void bfs(int s){
nclr(level);
queue<int> que;
level[s]=0;
que.push(s);
while(!que.empty()){
int v=que.front();
que.pop();
for(int i=0;i<G[v].size();i++){
edge &e=G[v][i];
if(e.cap>0 && level[e.to]<0){
level[e.to]=level[v]+1;
que.push(e.to);
}
}
}
}
ll dfs(int v, int t, ll f){
if(v==t)return f;
for(int &i=iter[v];i<G[v].size();i++){
edge &e=G[v][i];
if(e.cap>0 && level[v]<level[e.to]){
ll d=dfs(e.to, t, min(f,e.cap));
if(d>0){
e.cap-=d;
G[e.to][e.rev].cap+=d;
return d;
}
}
}
return 0;
}
ll max_flow(int s,int t){
ll flow=0;
while(true){
clr(iter);
bfs(s);
if(level[t]<0)return flow;
ll f;
while(f=dfs(s,t,INF)){
flow+=f;
}
}
return flow;
}
};
最小費用流
struct edge{int to;ll cap;ll cost;int rev;
};
typedef pair<ll,int> pli;
const int MAX_V=40;
ll INF=1LL<<62-1;
struct cal_min_cost_flow{
vector<edge> G[MAX_V];
ll h[MAX_V]; //potential
ll dist[MAX_V];
int prev_v[MAX_V];
int prev_e[MAX_V];
void add_edge(int from, int to, ll cap, ll cost){
G[from].pb( (edge){to,cap,cost,G[to].size()} );
G[to].pb( (edge){from,0,-cost,G[from].size()-1} );
}
ll min_cost_flow(int s, int t, ll f){
ll res=0;
REP(v,MAX_V)h[v]=0;
while(f>0){
REP(v,MAX_V)dist[v]=INF;
priority_queue<pli, vector<pli>, greater<pli> > Q;
Q.push(pli(0,s));
dist[s]=0;
while(!Q.empty()){
int v=Q.top().second; ll d=Q.top().first; Q.pop();
if(dist[v]<d)continue; //古いのが残ってるかも
assert(dist[v]==d);
REP(i,G[v].size()){
edge &e=G[v][i];
int nv=e.to;
ll nd=d+e.cost+h[v]-h[nv];
if(e.cap>0 && dist[nv]> nd ){
dist[nv]=nd;
prev_v[nv]=v;
prev_e[nv]=i;
Q.push(pli(nd, nv));
}
}
}
if(dist[t]==INF)return -1;
REP(v,MAX_V) h[v]+=dist[v];
ll d=f; //流す量
for(int v=t; v!=s; v=prev_v[v]){
d=min(d, G[prev_v[v]][prev_e[v]].cap) ;
}
f-=d;
res+=d*h[t];
for(int v=t; v!=s; v=prev_v[v]){
edge &e=G[prev_v[v]][prev_e[v]];
e.cap-=d;
G[v][e.rev].cap+=d;
}
}
return res;
}
};
グラフ
struct union_find{
vi par,rank;
union_find(int N){
par=vi(N);
rank=vi(N);
REP(i,N){
par[i]=i;
rank[i]=0;
}
}
int find(int x){
assert(x<par.size());
if(par[x]==x)return x;
return par[x]=find(par[x]);
}
void unite(int x, int y){
x=find(x);
y=find(y);
if(x==y)return;
if(rank[x]<rank[y])par[x]=y;
else{
par[y]=x;
if(rank[x]==rank[y])rank[x]++;
}
}
};
struct edge{
int to;
ll w;
};
/*bool comp_for_kruskal(const edge &e1, const edge &e2){
return e1.w > e2.w;
}*/
struct graph{
vector<vector<edge> > G;
graph(int N){
G=vector<vector<edge> >(N);
}
void add_edge(int s, int t, ll w){
G[s].pb((edge){t,w});
G[t].pb((edge){s,w});
}
vl dijkstra(int s){
vl ret(G.size(), -1);
priority_queue<pli,vector<pli>, greater<pli> > Q;
Q.push(pli(0,s));
while(!Q.empty()){
ll w=Q.top().first;
int t=Q.top().second;
Q.pop();
if(ret[t]!=-1)continue;
ret[t]=w;
REP(i,G[t].size()){
Q.push(pli(w+G[t][i].w, G[t][i].to));
}
}
return ret;
}
/*ll kruskal(){
vector<edge> all_edge;
REP(i,G.size()){
REP(j,G[i].size()) all_edge.pb(G[i][j]);
}
sort(all_edge.begin(), all_edge.end(), comp_for_kruskal);
union_find uf(G.size());
ll ret=0;
REP(i,all_edge.size()){
edge e=all_edge[i];
if( uf.find(e.from) != uf.find(e.to) ){
ret += e.w;
uf.unite(e.from, e.to);
}
}
return ret;
}*/
};
Range Minimun Query
struct RMQ{
vl a;
int n;
RMQ(vl z){
n=1;
while(n<z.size())n*=2;
a.clear();
a.resize(2*n,INF);
for(int i=0;i<z.size();i++){
a[i+n]=z[i];
}
for(int i=n-1;i>=1;i--){
a[i]=min(a[2*i], a[2*i+1]);
}
}
void updata(int pos, ll val){
pos+=n;
a[pos]=val;pos/=2;
while(pos){
a[pos]=min(a[pos*2], a[pos*2+1]);
pos/=2;
}
}
ll get(int from, int to){
ll ret=INF;
from+=n;
to+=n;
while(from<to){
if(from%2){
ret=min(ret, a[from]);
from++;
}
if(to%2){
ret=min(ret, a[to-1]);
to--;
}
from/=2;
to/=2;
}
return ret;
}
};
Fenwick_Tree
struct fenwick_tree{
vector<ll> x;
fenwick_tree(int n){
int m=1;
while(m<n)m*=2;
x=vector<ll> (m);
}
// [i,j)区間
void range(int i,int j, ll d){
if(i!=0){
range(0,j,d);
range(0,i,-d);
return;
}
j-=1;
for(j;j>=0;j=(j&(j+1))-1){
x[j]+=d;
}
}
ll point(int k){
ll ret=0;
for(;k<x.size(); k|=k+1) ret+=x[k];
return ret;
}
};
その他
辞書順でlb以上の最小元
string cal(string lb){
if(check(lb))return lb;
ll n=sz(lb);
string a;
bool ok=false;
for (ll pos = n-1; pos >=0 ; --pos){
a=string(lb.begin(), lb.begin()+pos+1);
for(char c=lb[pos]+1; c<='9'; c++){
a[pos]=c;
if(check(a))goto J;
}
}
return "";
J:
ll m=n-sz(a);
rep(k,m){
for(char c='0'; c<='9'; c++){
if(check(a+c)){
a+=c;
break;
}
}
}
assert(sz(a)==n);
return a;
}
AnagralListで使用。
string comp(string xs,vi xn,int th){
int k=0;
REP(i,xn.size())k+=xn[i];
if(k==0)return"";
REP(i,xs.size()){
char c=xs[i];
int m=xn[i];
if(m==0)continue;
xn[i]--;
ll g=comb(xn);
if(th<g){
string t;
t.push_back(c);
return t+comp(xs,xn,th);
}
xn[i]++;
th-=g;
}
}
struct ANT{
int x,y,dx,dy;
ANT(){x=0,y=0,dx=1,dy=0;}
void L(){
int ndx=-dy,ndy=dx;
dx=ndx;dy=ndy;
}
void R(){
L();L();L();
}
void W(){
x+=dx;y+=dy;
}
};
数列の推測
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <cstring>
#include <assert.h>
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define EACH(i,c) for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define dump(x) cerr << #x << " = " << (x) << endl;
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;
#define debug2(x) cerr << #x << " = [";REP(__ind,(x).size()){cerr << (x)[__ind] << ", ";}cerr << "] (L" << __LINE__ << ")" << endl;
#define clr(a) memset((a),0,sizeof(a))
#define nclr(a) memset((a),-1,sizeof(a))
#define pb push_back
using namespace std;
static const double EPS = 1e-5;
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;
ll mod=1000000007;
ll extgcd(ll a, ll b, ll &x, ll &y){
ll d=a;
if(b!=0){
d=extgcd(b, a%b, y, x);
y-=(a/b)*x;
}
else{
x=1,y=0;
}
return d;
}
ll modinverse(ll a, ll b){
ll x,y;
extgcd(a,b, x, y);
return (x%b+b)%b;
}
ll truemod(ll n, ll m){
return (n%m+m)%m;
}
ll det(vvl x){
ll h=1;
int n=x.size();
REP(i,n) REP(j,n) x[i][j]=truemod(x[i][j],mod);
REP(i,n){
FOR(j,i,n){
if(x[j][i]!=0 && j!=i){
REP(k,n)swap(x[j][k], x[i][k]);
h*=-1;
break;
}
}
if(x[i][i]==0)return 0;
ll v=modinverse(x[i][i], mod);
h=truemod(h*x[i][i],mod);
FOR(j,i+1,n){
ll v2=v*x[j][i]%mod;
REP(k,n) x[j][k]=truemod(x[j][k]-x[i][k]*v2,mod);
}
}
return h;
}
vvl inverseMatrix(vvl x, vvl y){
int n=x.size();
REP(i,n) REP(j,n){
x[i][j]=truemod(x[i][j], mod);
}
REP(i,n){
FOR(j,i,n){
if(x[j][i]!=0){
if(j!=i){
REP(k,n)swap(x[j][k], x[i][k]);
REP(k,y[0].size()) swap(y[j][k], y[i][k]);
}
break;
}
}
ll v=modinverse(x[i][i], mod);
REP(k,n)x[i][k]=truemod(x[i][k]*v, mod);
REP(k,y[0].size())y[i][k]=truemod(y[i][k]*v, mod);
REP(j,n) if(i!=j){
ll v2=x[j][i];
REP(k,n) x[j][k]=truemod(x[j][k]-x[i][k]*v2, mod);
REP(k,n) y[j][k]=truemod(y[j][k]-y[i][k]*v2, mod);
}
}
REP(i,x.size()){
debug2(x[i]);
}
return y;
}
vvl toeplitz(vl v, int start, int n){
vvl x(n);
REP(i,n)x[i].resize(n);
REP(i,n) REP(j,n) x[i][j]=v[start+i+j];
return x;
}
int main(){
vl v;
ll a=1,b=1;
REP(i,100){
v.push_back(a);
a=3*b+7*a;
b=2*a+5*b;
}
debug2(v);
FOR(i,1,10) cout << i << " " << det(toeplitz(v, 2, i)) << endl;
vvl z=inverseMatrix(toeplitz(v,0,2), toeplitz(v,1,2));
REP(i,z.size()){
debug2(z[i]);
}
return 0;
}
最終更新:2012年09月15日 08:02