<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      XVII Open Cup named after E.V. Pankratiev. XXI Ural Championship

      A. Apple

      按題意模擬即可。

      #include<stdio.h>
      #include<iostream>
      #include<string.h>
      #include<string>
      #include<ctype.h>
      #include<math.h>
      #include<set>
      #include<map>
      #include<vector>
      #include<queue>
      #include<bitset>
      #include<algorithm>
      #include<time.h>
      using namespace std;
      void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
      #define MS(x, y) memset(x, y, sizeof(x))
      #define ls o<<1
      #define rs o<<1|1
      typedef long long LL;
      typedef unsigned long long UL;
      typedef unsigned int UI;
      template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
      template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
      const int N = 105, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
      template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
      int casenum, casei;
      int n, m;
      vector<int>a[N];
      
      int ind1 = 0, ind1num = 0;
      int ind2num = 0;
      int ind3 = 0, ind3num = 0;
      bool vis[N];
      int ind[N];
      
      int cnt;
      bool dfs1(int x, int fa)
      {
          ++cnt;
          vis[x] = 1;
          for(auto y : a[x])if(y != fa)
          {
              if(!vis[y])
              {
                  if(!dfs1(y, x))return 0;
              }
              else if(y != ind3)return 0;
          }
          return 1;
      }
      
      void dfs3(int x, int fa)
      {
          ++cnt;
          vis[x] = 1;
          for(auto y : a[x])if(y != fa)
          {
              if(!vis[y])
              {
                  dfs3(y, x);
              }
          }
      }
      
      bool solve()
      {
          if(ind1num != 1)return 0;
          if(ind2num != n - 2)return 0;
          if(ind3num != 1)return 0;
      
          cnt = 0;
          vis[ind3] = true;
          if(!dfs1(ind1, 0))return 0;
          dfs3(ind3, 0);
          if(cnt != n)return 0;
      
          return 1;
      }
      int main()
      {
          freopen("input.txt", "r", stdin);
          freopen("output.txt", "w", stdout);
      	while(~scanf("%d%d", &n, &m))
      	{
              for(int i = 1; i <= n; ++i)
              {
                  a[i].clear();
                  ind[i] = 0;
                  vis[i] = 0;
              }
              for(int i = 1; i <= m; ++i)
              {
                  int x, y; scanf("%d%d", &x, &y);
                  a[x].push_back(y);
                  a[y].push_back(x);
                  ++ind[x];
                  ++ind[y];
              }
              ind1 = 0, ind1num = 0;
              ind2num = 0;
              ind3 = 0, ind3num = 0;
              for(int i = 1; i <= n; ++i)
              {
                  if(ind[i] == 1)
                  {
                      ++ind1num;
                      ind1 = i;
                  }
                  else if(ind[i] == 2)
                  {
                      ++ind2num;
                  }
                  else if(ind[i] == 3)
                  {
                      ++ind3num;
                      ind3 = i;
                  }
              }
              puts(solve() ? "Yes" : "No");
      	}
      
      	return 0;
      }
      /*
      【trick&&吐槽】
      
      
      【題意】
      
      
      【分析】
      
      
      【時間復雜度&&優化】
      9 9
      1 2
      2 3
      3 5
      5 6
      6 4
      4 7
      1 7
      7 9
      8 9
      
      5 5
      1 2
      2 3
      1 3
      1 4
      1 5
      
      4 4
      1 2
      2 3
      1 3
      1 4
      
      5 4
      1 2
      2 3
      1 3
      1 4
      
      
      */
      

        

      B. Bar charts

      關于序列的前綴和建立差分約束系統,SPFA判斷是否存在負環。

      #include<cstdio>
      #include<cstdlib>
      using namespace std;
      const int N=12222,M=1000000,E=10000000,inf=~0U>>1;
      int n,i,g[N],v[M],w[M],nxt[M],ed,d[N];
      int x,h,t,q[E];
      int vis[N],in[N];
      inline void add(int x,int y,int z){v[++ed]=y;w[ed]=z;nxt[ed]=g[x];g[x]=ed;}
      inline void make(int x,int y,int z){
          //x-y=z
          add(y,x,z);
          add(x,y,-z);
      }
      void gao(){
          int k,b,s;
          scanf("%d%d%d",&k,&b,&s);
          make(b-1,0,0);
          for(int i=b+k*s;i<=n;i++)make(i,i-1,0);
          for(int i=1;i<=k;i++){
              int l=b+(i-1)*s,r=b+i*s;
              int o;
              scanf("%d",&o);
              //s[r-1]-s[l-1]
              make(r-1,l-1,o);
          }
      }
      void NO(){
          puts("No");
          exit(0);
      }
      inline void ext(int x,int y){
          if(y<0)NO();
          if(y>=d[x])return;
          d[x]=y;
          if(!in[x]){
              in[x]=1;
              vis[x]++;
              if(vis[x]>=n)NO();
              q[++t]=x;
              if(t>=E-10)NO();
          }
      }
      int main(){
          freopen("input.txt","r",stdin);
          freopen("output.txt","w",stdout);
          n=11111;
          for(i=0;i<n;i++)add(i+1,i,0);
          gao();
          gao();
          for(i=0;i<=n;i++){
              d[i]=inf;
          }
          h=1,t=0;
          ext(0,0);
          while(h<=t){
              x=q[h++];
              for(i=g[x];i;i=nxt[i])ext(v[i],d[x]+w[i]);
              in[x]=0;
          }
          puts("Yes");
      }
      

        

      C. Construction sets

      二分答案,二進制拆分背包+bitset檢驗。

      #include<stdio.h>
      #include<iostream>
      #include<string.h>
      #include<string>
      #include<ctype.h>
      #include<math.h>
      #include<set>
      #include<map>
      #include<vector>
      #include<queue>
      #include<bitset>
      #include<algorithm>
      #include<time.h>
      using namespace std;
      void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
      #define MS(x, y) memset(x, y, sizeof(x))
      #define ls o<<1
      #define rs o<<1|1
      typedef long long LL;
      typedef unsigned long long UL;
      typedef unsigned int UI;
      template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
      template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
      const int N = 55, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
      template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
      int casenum, casei;
      int n, mn, mx;
      int m[N], c[N];
      bitset<10005>f;
      bool check(int K)
      {
          f.reset(); f[0] = 1;
          for(int i = 1; i <= n; ++i)
          {
              int tot = c[i] / K;
              int g = 1;
              LL v = m[i];
              while(tot)
              {
                  if(v > mx)break;
                  f |= f << v;
                  tot -= g;
                  g = min(g * 2, tot);
                  v = (LL)m[i] * g;
              }
          }
          for(int j = mn; j <= mx; ++j)
          {
              if(f[j])return 1;
          }
          return 0;
      }
      int main()
      {
          freopen("input.txt", "r", stdin);
          freopen("output.txt", "w", stdout);
      	while(~scanf("%d%d%d", &n, &mn, &mx))
      	{
              for(int i = 1; i <= n; ++i)
              {
                  scanf("%d%d", &m[i], &c[i]);
              }
              int l = 0;
              int r = 1e6;
              while(l < r)
              {
                  int mid = (l + r + 1) >> 1;
                  if(check(mid))
                  {
                      l = mid;
                  }
                  else
                  {
                      r = mid - 1;
                  }
              }
              printf("%d\n", l);
      	}
      
      	return 0;
      }
      /*
      【trick&&吐槽】
      
      
      【題意】
      
      
      【分析】
      
      
      【時間復雜度&&優化】
      3 12 13
      3 8
      4 6
      7 9
      
      */
      

        

      D. Dinner party

      $f[i][j]$表示面積和為$i$的矩形,周長和為$j$是否有可能,bitset加速。

      #include<cstdio>
      #include<bitset>
      using namespace std;
      const int N=1010,M=2010;
      int T,n,m,i,j,x,y,cnt;
      bitset<M>f[N];
      void solve(){
          scanf("%d%d",&n,&m);
          if(m%2){
              puts("No");
              return;
          }
          m/=2;
          if(f[n][m]==0){
              puts("No");
              return;
          }
          puts("Yes");
          int cnt=0;
          static int q[100000][2];
          while(n){
              int X=0,Y=0;
              for(x=1;x<=n;x++){
                  for(y=1;y*x<=n;y++)if(x+y<=m)if(f[n-x*y][m-x-y]){
                      X=x,Y=y;
                      break;
                  }
                  if(X)break;
              }
              q[++cnt][0]=X;
              q[cnt][1]=Y;
              n-=X*Y;
              m-=X+Y;
          }
          printf("%d\n",cnt);
          for(int i=1;i<=cnt;i++)printf("%d %d\n",q[i][0],q[i][1]);
      }
      int main(){
          freopen("input.txt","r",stdin);
          freopen("output.txt","w",stdout);
          //scanf("%d%d",&n,&m);
          n=1000;
          m=2000;
          f[0][0]=1;
          for(i=0;i<=n;i++)
              for(x=1;x+i<=n;x++)
                  for(y=1;x*y+i<=n;y++)
                      f[i+x*y]|=f[i]<<(x+y);
          scanf("%d",&T);
          while(T--)solve();
      }
      

        

      E. Expression on dice

      若要構造$=$,則在兩側構造$0$即可,否則隨意構造。

      //
      //  main.cpp
      //  opencup 10378 E
      //
      //  Created by luras on 2017/9/14.
      //  Copyright ? 2017年 luras. All rights reserved.
      //
      
      #define ms(x, y) memset(x, y, sizeof(x))
      #define mc(x, y) memcpy(x, y, sizeof(x))
      #define lson o << 1, l, mid
      #define rson o << 1 | 1, mid + 1, r
      #define ls o << 1
      #define rs o << 1 | 1
      #include<stdio.h>
      #include<string.h>
      #include<math.h>
      #include<queue>
      #include<map>
      #include<stack>
      #include<time.h>
      #include<vector>
      #include<list>
      #include<set>
      #include<iostream>
      #include<stdlib.h>
      #include<string>
      #include<algorithm>
      #pragma comment(linker,"/STACK:102400000,102400000")
      template <class T> inline void gmax(T &a, T b){if(b > a) a = b;}
      template <class T> inline void gmin(T &a, T b){if(b < a) a = b;}
      using namespace std;
      const int N = 1e6 + 10, M = 2e6 + 10, Z = 1e9 + 7, maxint = 2147483647, ms1 = 16843009, ms31 = 522133279, ms63 = 1061109567, ms127 = 2139062143;
      const double PI = acos(-1.0), eps = 1e-8;
      typedef long long LL;
      void fre()
      {
          freopen("/Users/luras/Desktop/in.txt", "r", stdin);
          freopen("/Users/luras/Desktop/out.txt", "w", stdout);
      }
      const int INF = 1e9;
      int casenum, casei;
      
      int priv[N];
      double calc(double a, double b, char op)
      {
          if(op == '+') return a + b;
          if(op == '-') return a - b;
          if(op == '*') return a * b;
          if(op == '/') return a / b;
          return 0;
      }
      
      
      double calculate(string str)
      {
          stack<double> num;
          stack<char> oper;
          priv['+'] = priv['-'] = 3;
          priv['*'] = priv['/'] = 2;
          priv['('] = 10;
          double x, y, t = 0;
          int i; char last = 0;
          for(i = 0; i < str.length(); i ++){
              if(isdigit(str[i])){
                  num.push(atof(str.c_str() + i));
                  for(; i + 1 < str.length() && isdigit(str[i + 1]); i ++);
                  if(i + 1 < str.length() && str[i + 1] == '.')
                      for(i ++; i + 1 < str.length() && isdigit(str[i + 1]); i ++);
              }
              else if(str[i] == '('){
                  oper.push(str[i]);
              }
              else if(str[i] == ')'){
                  while(oper.top() != '('){
                      y = num.top(); num.pop();
                      x = num.top(); num.pop();
                      char op = oper.top();
                      oper.pop();
                      num.push(calc(x, y, op));
                  }
                  oper.pop();
              }
              else if(str[i] == '-' && (last == 0 || last == '(')){
                  num.push(0.0);
                  oper.push('-');
              }
              else if(priv[str[i]] > 0){
                  while(oper.size() > 0 && priv[str[i]] >= priv[oper.top()]){
                      y = num.top(); num.pop();
                      x = num.top(); num.pop();
                      char op = oper.top();
                      oper.pop();
                      num.push(calc(x, y, op));
                  }
                  oper.push(str[i]);
              }else continue;
              last = str[i];
          }
          while(oper.size() > 0){
              y = num.top(); num.pop();
              x = num.top(); num.pop();
              char op = oper.top();
              oper.pop();
              num.push(calc(x, y, op));
          }
          return num.top();
      }
      
      map<int, bool> mop;
      vector<int> num;
      vector<char> sym;
      int lft, rgt, zero, divi, typ;
      
      
      const string sta[6][6] ={
          {"=", "<", ">", "!=", "<=", ">="},
          {"4", "+", "-", "(", "(", ")"},
          {"0", "/", "/", "/", "8", "+"},
          {"2", "3", "4", "5", "-", ")"},
          {"+", "-", "*", "/", "1", "9"},
          {"6", "7", "+", "-", "(", ")"}
      };
      
      
      void ask(int o)
      {
          char ch;
          if(o == 2){
              puts("2");
              fflush(stdout);
              scanf(" %c", &ch);
              //ch = sta[1][rand() % 6][0];
              //cout << "A: " << ch;
              if(ch == '(') lft ++;
              else if(ch == ')') rgt ++;
              else if(ch == '4') {
                  num.push_back(ch);
                  if(mop[ch] == 0){
                      mop[ch] = 1;
                      typ ++;
                  }
              }
              else sym.push_back(ch);
          }
          else if(o == 3){
              puts("3");
              fflush(stdout);
              scanf(" %c", &ch);
              //ch = sta[2][rand() % 6][0];
              //cout << "A: " << ch;
              
              if(ch == '0') zero ++;
              else if(ch == '8') {
                  num.push_back(ch);
                  if(mop[ch] == 0){
                      mop[ch] = 1;
                      typ ++;
                  }
              }
              else if(ch == '/') divi ++;
              else sym.push_back(ch);
          }
          else if(o == 4){
              puts("4");
              fflush(stdout);
              //ch = sta[3][rand() % 6][0];
              //cout << "A: " << ch;
              
              scanf(" %c", &ch);
              if(ch == '-') sym.push_back(ch);
              else if(ch == ')') rgt ++;
              else {
                  num.push_back(ch);
                  if(mop[ch] == 0){
                      mop[ch] = 1;
                      typ ++;
                  }
              }
          }
      }
      
      
      string ans;
      string s;
      string ss;
      
      int sgn(double x)
      {
          if(fabs(x) < eps) return 0;
          return x > 0 ? 1 : -1;
      }
      
      bool choose()
      {
          s = "";
          int DIV = divi, ZERO = zero;
          int n = num.size(), m = sym.size() + DIV;
          int bas = (n + ZERO) / (m + 1);
          int mo = (n + ZERO) - (m + 1) * bas;
          int t = 0, j = -1, k = -1;
          for(int i = 0; i < m + 1; i ++){
              if(mo){
                  if(j + 1 >= n) return 0; // 必須得放前導0了
                  s += num[++ j]; ++ t;
                  while(t <= bas && ZERO){
                      s += '0'; t ++; ZERO --;
                  }
                  while(t <= bas){
                      s += num[++ j]; t ++;
                  }
                  mo --;
                  t = 0;
              }
              else{
                  if(j + 1 >= n) return 0;
                  s += num[++ j]; ++ t;
                  while(t < bas && ZERO){
                      s += '0'; t ++; ZERO --;
                  }
                  while(t < bas){
                      s += num[++ j]; t ++;
                  }
                  t = 0;
              }
              if(DIV){
                  s += '/';
                  DIV --;
              }
              else{
                  if(k + 1 < sym.size())s += sym[++ k];
              }
          }
          return 1;
      }
      
      bool check(int o)
      {
          if(o == 0){
              zero -= 2; lft --; rgt --; divi --;
              if(!choose()) {zero += 2; lft ++; rgt ++; divi ++; return 0;}
              if(calculate(s) != 0){
                  ans = "";
                  for(int i = 0; i < lft; i ++) ans += '(';
                  ans += '0';
                  for(int i = 0; i < rgt; i ++) ans += ')';
                  ans += "=0/(" + s + ')';
              }
              else {zero += 2; lft ++; rgt ++; divi ++; return 0;}
          }
          else{
              zero --;
              if(!choose()) {zero ++;return 0;}
              double tmp = calculate(s);
              if(sgn(tmp) != 0){
                  if(ss[0] == '<' && sgn(tmp) > 0 || ss[0] == '>' && sgn(tmp) < 0){
                      ans = "";
                      for(int i = 0; i < lft; i ++) ans += '(';
                      ans += '0';
                      for(int i = 0; i < lft; i ++) ans += ')';
                      ans += ss + s;
                  }
                  else{
                      ans = "";
                      for(int i = 0; i < lft; i ++) ans += '(';
                      ans += s;
                      for(int i = 0; i < lft; i ++) ans += ')';
                      ans += ss + '0';
                  }
              }
              else if(ss == "!="){
                  ans = "";
                  for(int i = 0; i < lft; i ++) ans += '(';
                  ans += '0';
                  for(int i = 0; i < lft; i ++) ans += ')';
                  ans += ss + s;
                  
              }
              else {zero ++; return 0;}
          }
          return 1;
      }
      
      int main()
      {
          srand(time(NULL));
          //fre();
          puts("1");
          fflush(stdout);
          cin >> ss;
          //ss = sta[0][rand() % 6];
          //cout << ss << endl;
          lft = rgt = zero = divi = typ = 0;
          int tim = 0;
          while(1){
              if(++ tim == 1000){
                  int go = 1;
              }
              if(zero < (ss[0] == '=' ? 2 : 1) || divi == 0){
                  ask(3);
              }
              else if(lft < rgt || lft == 0){
                  ask(2);
              }
              else if(num.size() - 2 < sym.size() || rgt < lft){
                  ask(4);
              }
              else {
                  if(check(ss[0] == '=' ? 0 : 1)) break;
                  ask(4);
              }
          }
          printf("0 ");
          cout << ans << endl;
          fflush(stdout);
          return 0;
      }
      
      /*
       
       
       題意:
       
       類型:
       
       分析:
       
       優化:
       
       trick:
       
       數據:
       
       Sample Input
       
       Sample Output
       
       >=
       + / / + 8 0 ) ( ) ( - - 5 5 5 - 4 4 4 - 5 3
       
       */
      

        

      F. Flight trip

      留坑。

       

      G. Glasses with solutions

      找出的子集需要滿足$b\sum m-a\sum t=0$,折半搜索即可。

      #include<cstdio>
      #include<map>
      using namespace std;
      typedef long long ll;
      const int N=40;
      int n,m,A,B,i,x,y,a[N];map<ll,ll>f;
      ll ans;
      void dfsl(int x,ll y){
          if(x==m){f[y]++;return;}
          dfsl(x+1,y+a[x]);
          dfsl(x+1,y);
      }
      void dfsr(int x,ll y){
          if(x==n){ans+=f[-y];return;}
          dfsr(x+1,y+a[x]);
          dfsr(x+1,y);
      }
      int main(){
          freopen("input.txt","r",stdin);
          freopen("output.txt","w",stdout);
          scanf("%d%d%d",&n,&A,&B);
          for(i=0;i<n;i++){
              scanf("%d%d",&x,&y);
              a[i]=x*B-A*y;
          }
          m=n/2;
          dfsl(0,0);
          dfsr(m,0);
          ans--;
          printf("%lld",ans);
      }
      

        

      H. Hamburgers

      對于每個漢堡,$O(2^6)$枚舉所有它可以滿足的口味,然后對于每個人判斷是否滿足即可。

      時間復雜度$O(m\sum a+2^6\sum b)$。

      #include<cstdio>
      #include<cstring>
      #include<vector>
      using namespace std;
      const int N=55555;
      int n,m,i,j,k,x,ans[N],mx[N],b[N];
      vector<int>a[N];
      bool v[(1<<26)+5];
      inline int get(){
          static char s[1000];
          scanf("%s",s);
          int t=0,len=strlen(s);
          for(int i=0;i<len;i++)t|=1<<(s[i]-'a');
          return t;
      }
      inline void make(int x,int y){
          for(int i=x;i;i=(i-1)&x)v[i]=y;
      }
      int main(){
          freopen("input.txt","r",stdin);
          freopen("output.txt","w",stdout);
          scanf("%d",&n);
          for(i=1;i<=n;i++){
              scanf("%d",&k);
              while(k--){
                  x=get();
                  a[i].push_back(x);
              }
              ans[i]=1;
          }
          scanf("%d",&m);
          for(i=1;i<=m;i++){
              scanf("%d",&k);
              for(j=1;j<=k;j++)b[j]=get();
              for(j=1;j<=k;j++)make(b[j],1);
              for(j=1;j<=n;j++){
                  int t=0;
                  for(x=0;x<a[j].size();x++)if(v[a[j][x]])t++;
                  if(t>mx[j])mx[j]=t,ans[j]=i;
              }
              for(j=1;j<=k;j++)make(b[j],0);
          }
          for(i=1;i<=n;i++)printf("%d\n",ans[i]);
      }
      /*
      5
      1
      a
      3
      a
      ba
      cb
      3
      vba
      d
      ba
      3
      ca
      da
      da
      3
      as
      ba
      af
      2
      4
      abc
      abcd
      a
      a
      2
      abcdef
      abcdev
      */
      

        

      I. Intricate path

      留坑。

       

      J. Jumps through the Hyperspace

      顯然到每個點的時間越早越好,對于每種傳送門預處理出每種余數下的最優等待時間即可。

      #include<cstdio>
      #include<algorithm>
      #include<vector>
      #include<queue>
      using namespace std;
      typedef pair<int,int>P;
      const int N=2010,inf=~0U>>1;
      int n,m,st,i,j,a[N],b[N],c[N],d[N],w[N][N];
      int f[N];
      char g[N][N],op[N];
      priority_queue<P,vector<P>,greater<P> >q;
      inline void ext(int x,int y){
          if(f[x]>y)q.push(P(f[x]=y,x));
      }
      int main(){
          freopen("input.txt","r",stdin);
          freopen("output.txt","w",stdout);
          scanf("%d%d%d",&n,&m,&st);
          while(m--){
              scanf("%s",op);
              int o=op[0];
              scanf("%d%d%d%d",&a[o],&b[o],&c[o],&d[o]);
              for(i=0;i<c[o];i++){
                  w[o][i]=inf;
                  for(j=0;j<c[o];j++)w[o][i]=min(w[o][i],(a[o]*(i+j)+b[o])%c[o]+d[o]+j);
              }
          }
          for(i=1;i<=n;i++)scanf("%s",g[i]+1);
          for(i=1;i<=n;i++)f[i]=inf;
          ext(1,st);
          while(!q.empty()){
              P t=q.top();q.pop();
              if(f[t.second]<t.first)continue;
              for(i=1;i<=n;i++)if(g[t.second][i]!='.')
                  ext(i,t.first+w[g[t.second][i]][t.first%c[g[t.second][i]]]);
          }
          if(f[n]==inf)puts("-1");else 
          printf("%d",f[n]-st);
      }
      

        

      K. King’s island

      暴力搜索出一個上凸殼,然后翻轉拼接起來得到完整的多邊形即可。

      #include<stdio.h>
      #include<iostream>
      #include<string.h>
      #include<string>
      #include<ctype.h>
      #include<math.h>
      #include<set>
      #include<map>
      #include<vector>
      #include<queue>
      #include<bitset>
      #include<algorithm>
      #include<time.h>
      using namespace std;
      void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
      #define MS(x, y) memset(x, y, sizeof(x))
      #define ls o<<1
      #define rs o<<1|1
      typedef long long LL;
      typedef unsigned long long UL;
      typedef unsigned int UI;
      template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
      template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
      const int N = 1010, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
      template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
      int casenum, casei;
      int n;
      struct B
      {
          int x, y;
          bool operator < (const B & b)const
          {
              //y/x > b.y/b.x
              return y * b.x > x * b.y;
          }
      };
      B p[100000]; int g;
      int f[N][N][62];
      struct A
      {
          int x, y, z;
      };
      bool bingo[60];
      vector<B>ans[60];
      
      void getvt(int x, int y, int v, vector<B>&vt, int DX, int DY)
      {
          if(v == 0)return;
          int o = f[x][y][v];
          if(f[x - p[o].x][y - p[o].y][v] == o)
          {
              getvt(x - p[o].x, y - p[o].y, v, vt, DX + p[o].x, DY + p[o].y);
          }
          else
          {
              vt.push_back({p[o].x + DX, p[o].y + DY});
              getvt(x - p[o].x, y - p[o].y, v - 1, vt, 0, 0);
          }
      }
      
      void init()
      {
          for(int i = 1; i <= 200; ++i)
          {
              for(int j = i + 1; j <= 200; ++j)if(__gcd(i, j) == 1)
              {
                  int W = (i * i + j * j);
                  int w = sqrt(W);
                  if(w * w == W)
                  {
                      p[++g] = {i, j};
                      p[++g] = {j, i};
                  }
              }
          }
          sort(p + 1, p + g + 1);
          //printf("%d\n", g);
      
          MS(f, 0);
          f[0][0][0] = 1;
          for(int i = 0; i <= 500; ++i)
          {
              for(int j = 0; j <= 500; ++j)
              {
                  for(int v = 29; v >= 0; --v)if(f[i][j][v])
                  {
                      //
                      int k = f[i][j][v];
                      auto &it = f[i + p[k].x][j + p[k].y][v];
                      if(it == 0)it = k;
                      //
                      for(int k = f[i][j][v] + 1; k <= g; ++k)
                      {
                          auto &it = f[i + p[k].x][j + p[k].y][v + 1];
                          if(it == 0)it = k;
                      }
                      if(i == 0 || j == 0)continue;
                      for(int u = 1; u + v <= 30; ++u)if(f[i][j][u] && f[i][j][u] != f[i][j][v])
                      {
                          if(!bingo[u + v])
                          {
                              bingo[u + v] = 1;
                              vector<B>up, down;
                              getvt(i, j, u, up, 0, 0);
                              getvt(i, j, v, down, 0, 0);
                              int x = i;
                              int y = j;
                              //printf("%d %d %d\n", u + v, up.size(), down.size());
                              //puts("up------------");
                              for(int r = 0; r < up.size(); ++r)
                              {
                                  x -= up[r].x;
                                  y -= up[r].y;
                                  ans[u + v].push_back({x, y});
                                  //printf("%d %d\n", up[r].x, up[r].y);
                              }
                              //puts("down------------");
                              for(int r = 0; r < down.size(); ++r)
                              {
                                  x += down[r].x;
                                  y += down[r].y;
                                  ans[u + v].push_back({x, y});
                                  //printf("%d %d\n", down[r].x, down[r].y);
                              }
                              //puts("ans------");
                              for(auto w : ans[u + v])
                              {
                                  //printf("%d %d\n", w.x, w.y);
                              }
                              int pasue = 1;
                          }
                      }
                  }
              }
          }
          for(int i = 1;i <= 30; ++i)
          {
              //printf("%d\n", bingo[i]);
          }
      }
      int main()
      {
          freopen("input.txt", "r", stdin);
          freopen("output.txt", "w", stdout);
          init();
      	while(~scanf("%d", &n))
      	{
      	    if(n == 3)
              {
                  puts("0 0\n4 3\n-20 21");
                  continue;
              }
              for(auto it : ans[n])
              {
                  printf("%d %d\n", it.x, it.y);
              }
      	}
      
      	return 0;
      }
      /*
      【trick&&吐槽】
      
      
      【題意】
      
      
      【分析】
      
      
      【時間復雜度&&優化】
      28 195
      9 15
      -116 178
      4
      20 21
      1 -159
      -236 -11
      -92 6
      5
      20 50
      3 -94
      -16 -274
      -236 18
      -92 35
      
      
      */
      

        

      L. Lexica

      無視同一行/同一列的兩個格子的位置關系,只需要在它們不相同時將方案數乘$2$,如此一來只關心每一行/每一列有多少格子沒滿足。

      設$f[i][j][S][k]$表示考慮到$(i,j)$,每一列剩余情況為$S$,第$i$行還有$k$個格子需要填充時的方案數,然后逐格轉移即可。

      時間復雜度$O(n3^n)$。

      #include<cstdio>
      typedef unsigned long long ll;
      const int N=18,M=1600000;
      int n,m,all,i,j,k,x,y,z,A,B,C,S,o,p[N],mask,cnt[N];
      char a[N][N];
      int e;
      ll f[2][M][3],mul;
      int w[M];
      inline void clr(){
          for(int i=0;i<=mask;i++)for(int j=0;j<3;j++)f[e^1][i][j]=0;
      }
      inline void nxt(){
          //for(int i=0;i<=mask;i++)for(int j=0;j<3;j++)f[i][j]=g[i][j];
      }
      inline int get(int S,int x){
          return S/p[x]%3;
      }
      void dfs(int x,int y,int z){
      		if(x==n){
      			w[y]=z;
      			return;
      		}
      		for(int i=0;i<3;i++)dfs(x+1,y*3+i,z*2+(!!i));
      }
      int main(){
          freopen("input.txt","r",stdin);
          freopen("output.txt","w",stdout);
          scanf("%d",&n);
          m=n+2;
          for(i=0;i<m;i++)scanf("%s",a[i]);
          mul=1;
          for(p[0]=i=1;i<N;i++)p[i]=p[i-1]*3;
          all=p[n];
          for(i=1;i<=n;i++){
              if(a[0][i]!='#'&&a[m-1][i]!='#'&&a[0][i]!=a[m-1][i])mul*=2;
              if(a[i][0]!='#'&&a[i][m-1]!='#'&&a[i][0]!=a[i][m-1])mul*=2;
              if(a[i][0]!='#')cnt[i]++;
              if(a[i][m-1]!='#')cnt[i]++;
              if(a[0][i]!='#')mask+=p[i-1];
              if(a[m-1][i]!='#')mask+=p[i-1];
          }
          dfs(0,0,0);
          f[0][mask][0]=mul;
          for(i=1;i<=n;i++){
              clr();
              int o=cnt[i];
              for(A=0;A<=mask;A++)f[e^1][A][o]=f[e][A][0];
              e^=1;
              for(j=0;j<n;j++)if(a[i][j+1]=='.'){
                  clr();
                  for(S=0;S<=mask;S++){
                  		if(w[S]>>j&1)for(k=0;k<=o;k++)if(f[e][S][k])f[e^1][S-p[j]][k]+=f[e][S][k];
                  		for(k=1;k<=o;k++)if(f[e][S][k])f[e^1][S][k-1]+=f[e][S][k];
                  }
                  e^=1;
              }
          }
          printf("%llu",f[e][0][0]);
      }
      /*
      5
      ##ARRR#
      H.#.##S
      Y.....E
      O.#.#.E
      ##....E
      ###.#.E
      #XNT#A#
      */
      

        

      M. Maximal paths

      樹形DP求出每個點內部從葉子往上、從上往下的最大數字串即可。需要手寫高精度。

      #include<cstdio>
      #include<algorithm>
      using namespace std;
      typedef unsigned long long ll;
      typedef __int128 lll;
      const int N=10000010,M=50;
      const ll MO=1000000000000000000ULL;
      int n,i;char a[N];
      struct P{
          ll v[3];
          P(){v[0]=v[1]=v[2]=0;}
          P operator+(int b){
              P c;
              for(int i=0;i<3;i++)c.v[i]=v[i];
              c.v[0]+=b;
              for(int i=0;i<2;i++)if(c.v[i]>=MO){
                  c.v[i+1]+=c.v[i]/MO;
                  c.v[i]-=MO;
              }
              return c;
          }
          P operator+(const P&b){
              P c;
              for(int i=0;i<3;i++)c.v[i]=v[i]+b.v[i];
              for(int i=0;i<2;i++)if(c.v[i]>=MO){
                  c.v[i+1]+=c.v[i]/MO;
                  c.v[i]-=MO;
              }
              return c;
          }
          P operator*(int b){
              P c;
              for(int i=0;i<3;i++)c.v[i]=v[i]*b;
              for(int i=0;i<2;i++)c.v[i+1]+=c.v[i]/MO,c.v[i]%=MO;
              c.v[2]%=MO;
              return c;
          }
          P operator*(const P&b){
              P c;
              static lll f[3];
              f[0]=f[1]=f[2]=0;
              for(int i=0;i<3;i++)if(v[i])for(int j=0;i+j<3;j++)if(b.v[j])f[i+j]+=(lll)v[i]*b.v[j];
              for(int i=0;i<2;i++)if(f[i]>=MO)f[i+1]+=f[i]/MO,f[i]%=MO;
              if(f[2]>=MO)f[2]%=MO;
              for(int i=0;i<3;i++)c.v[i]=f[i];
              return c;
          }
          void up(const P&b){//max=
              int i;
              for(i=2;~i;i--)if(b.v[i]!=v[i])break;
              if(i<0)return;
              if(b.v[i]<v[i])return;
              for(i=0;i<3;i++)v[i]=b.v[i];
          }
          void write(){
              int i=2;
              while(i&&!v[i])i--;
              printf("%llu",v[i]);
              for(int j=i-1;~j;j--)printf("%018llu",v[j]);
              puts("");
          }
      }f[M],g[M],p[M],ans,ff,gg,mx[M];
      int d[M];
      unsigned int seed,base;
      void dfs(int x,int k){
          f[k]=g[k]=mx[k]=P();
          d[k]=0;
          for(int i=0;i<2;i++){
              int y=x<<1|i;
              if(y>n)continue;
              dfs(y,k+1);
              ff=(f[k+1]*10)+((int)a[y]);
              gg=g[k+1]+(p[d[k+1]]*((int)a[y]));
              mx[k].up((ff*p[d[k]])+g[k]);
              mx[k].up((f[k]*p[d[k+1]+1])+gg);
              /*if(x==1){
                  puts("debug");
                  ff.write();
                  f[k].write();
              }*/
              f[k].up(ff);
              g[k].up(gg);
              d[k]=max(d[k],d[k+1]+1);
              /*if(x==1){
                  puts("debug");
                  ff.write();
                  f[k].write();
              }*/
          }
         /* printf("%d:\n",x);
          f[k].write();
          g[k].write();
          mx[k].write();*/
          ans=ans+mx[k];
      }
      int main(){
          freopen("input.txt","r",stdin);
          freopen("output.txt","w",stdout);
          scanf("%d%u",&n,&seed);
          base=(1U<<31)-1;
          p[0].v[0]=1;
          for(i=1;i<M;i++)p[i]=p[i-1]*10;
          for(i=1;i<=n;i++){
              a[i]=((seed&base)>>16)%9+1;
              seed=seed*1103515245+12345;
              //printf("%d\n",a[i]); i and i/2
          }
          dfs(1,0);
          ans.write();
      }
      

        

      posted @ 2017-09-15 02:00  Claris  閱讀(634)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲一区二区三区啪啪| 集安市| 五月天国产成人av免费观看| 国产色悠悠在线免费观看| 动漫AV纯肉无码AV电影网| 日韩精品射精管理在线观看| 成人免费A级毛片无码网站入口| 激情国产一区二区三区四区 | 视频一区二区三区在线视频| 中文字幕日韩一区二区不卡| 国产成人无码AV片在线观看不卡 | 日韩中文字幕国产精品| 国产69久久精品成人看| 久久自己只精产国品| 青青国产揄拍视频| 国产人妻精品无码av在线| 高清不卡一区二区三区| 亚洲成人av一区免费看| 日日碰狠狠躁久久躁96avv| a男人的天堂久久a毛片| 精品一区二区三区女性色| 亚洲国产精品嫩草影院久久 | 日韩av一区二区高清不卡| 亚洲大尺度无码专区尤物| 最新国产在线拍揄自揄视频 | 国产91麻豆精品成人区| 中文字幕在线精品视频入口一区| 亚洲婷婷综合色高清在线| 午夜福利精品一区二区三区| 国产老头多毛Gay老年男| 国产欧美日韩亚洲一区二区三区| 亚洲国产日韩a在线亚洲| 亚洲国产成人av国产自| 国产一区日韩二区欧美三区| 视频一区二区三区刚刚碰| 少妇人妻偷人免费观看| bt天堂新版中文在线| 国产精品∧v在线观看| 亚洲一区在线成人av| 阳高县| 久久91精品牛牛|