USACO 5.5 chapters

Picture

Subject to the effect

ion 1998

Seeking n (<= 5000) covering a perimeter pattern of rectangular (including holes), coordinate range[-10000,10000]

answer

One-dimensional discrete +2 tree line, but think carefully not enough space, time, reluctantly accepted

Then visually possible 1-dimensional scanning the line segment tree +?

Then even scan lines may over-bare, as in the following code

The total number of order of magnitude in terms of input O(n), sorting O(n log n), scanning process O(sum(len周长))about 5000*20000*4the upper limit [but USACO gave up,

So it is still a good segment tree?

From the implementation is concerned, the rectangular split into x and y directions, by counting the accumulated number of layers of each block boundary is determined

#include <bits/stdc++.h>
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)

using namespace std;

const string filename = "picture";

void usefile(){
  freopen((filename+".in").c_str(),"r",stdin);
  freopen((filename+".out").c_str(),"w",stdout);
}

int N,ans=0;
// OX向和OY向的 线段分离处理,互不影响
tuple<int,bool,int,int> Lx[10010],Ly[10010]; // {位置idx坐标,结束边bool?,st->end}
int level[20010];


void Scan(tuple<int,bool,int,int> *L) {
  sort(L,L+N);
  rep(i,0,20001)
    level[i]=0;
  rep(i,0,N){
    rep(j,get<2>(L[i]),get<3>(L[i])){
      if (!get<1>(L[i])){
        ans += level[j+10000]==0;
        level[j+10000]++;
      } else {
        level[j+10000]--;
        ans += level[j+10000]==0;
      }
    }
  }
}


int main(){
  usefile();
  scanf("%d",&N);
  rep(i,0,N){
    int x1,x2,y1,y2;
    scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
    // OX 方向边
    Lx[i*2] = {y1,false,x1,x2};
    Lx[i*2+1] = {y2,true,x1,x2};
    // OY 方向边
    Ly[i*2] = {x1,false,y1,y2};
    Ly[i*2+1] = {x2,true,y1,y2};
  }
  N*=2;
  Scan(Lx);
  Scan(Ly);
  printf("%d\n",ans);
  return 0;
}

Hidden Password

ACM South Eastern Europe -- 2003

Subject to the effect

String L (length <=100’000)

To find the string, after the translation, the first letter of all the strings in the string lexicographically smallest index in the original string

As cba

All strings acb bac cab, (sorted), corresponding to the first letter of the first string of the original string 2 position (counting from 0)

answer

enumerate!

We first find the smallest letter sweep againO(n)

Then find the coordinates of the start of

Gradually increasing the length of the

So we have a recursive relationship, to ensure that after each increase in length, but also the rest of the current coordinate leaving only the smallest,

Therefore, when the length increases l, we maintain the initial coordinates of the entire string, the length from 1the lsmallest are lexicographically

So we have two ways to change the length

  1. +1

Assuming that all point to the length expansion does not belong to the current point of maintenance, then the length plus 1, retention, increase the minimum dot character

example abcabdzzzabc

All initial acoordinates [0,3,9], length1

Expansion, expansion targets, respectively [1,4,10], are not currently being maintained point ( [0,3,9])

It is more elements, the whole is b, the length=1+1=2

Next, the goal is to expand [2,5,11], it is not a maintenance point

Compare characters, two abc, one abd, it becomes a maintenance point [0,9], length becomes=2+1=3

Further expansion, the expansion target [3,0], noting 0that our current maintenance of [0,9]the elements, so do not take +1the program

  1. Multiply

Suppose characters aabbabbb,

After then find the smallest characters, starting coordinates left [0,1,4], once you found any expansion of a next ( [1,2,5]) is to maintain a point, then double length, after deleting a point, in this case, the expansion of position not the smallest point coordinates directly removed.

Because we maintain == point from 1 to the length, the length of each is lexicographically smallest, so there is no point in the maintenance, are non lexicographically smallest, can be multiplied

Remove the right point because lexicographical point of expansion of the right to maintain a certain point greater than or equal to the left of the case by the arbitration ring of equal treatment

As discovered after an expansion 0in a expansion is 1, and 1that we maintain the point, so the length of = 1*2, 1point deletion, 4expansion is 5then 5not maintained, so the 4point is also deleted, the last remaining Summing0

The problems described above: The starting point is at what point?

Assumptions string aaazzaaza,

Obviously after the initial operating point has to be maintained[0,1,2,5,6,8]

Note that, if handled from left to right, in accordance with the above algorithm will become [0,6,8???], and the actual nature of the ring from the point of view, should be expected to get [1,6,8], which is the 8position seen as [8,0,1,2]the starting point of this paragraph.

Find here plus a parent node, find the left-most point to the point on the ring corresponding sense, look at the bottom of the function of the word is circle,

Meanwhile, circlehere, if found, the entire ring saved dots, then only these points is equivalent to the ring on the lexicographic order, in accordance with the minimum desired title index In this case, the answer to that is taken


Space complexity, emmmm nothing to say, you can look at variables, maintained atO(n)

time complexity,

Each will multiply the number of points divided by at least 2, because a point to stay, then the first of its extension to the original point of maintenance, the need for maintenance and the next to disappear, so every time you want to stay a point, it must be deleted a point, the point will not be left there, it must leave the last half or less

O(n+n/2+n/4) = O(2n) = O(n)

Consideration of any length are +1, then each can perform limit is +1

sum(n*(1+1/2+...1/n))

As we all know this is an infinite series, so the time complexity infinite

Also from large O(12n)=O(n)complexity,

Here is the fact, that these two interludes, some less so O(2n+12n)=O(n), (mathematical habits bother classification ranging discussions can be used on the line, so a stay equal)

To sum up time and space are met

char s[100010];
int sz=0;

bool pos[100010];
vector<int>p;
vector<int>q;
int L;

bool circle(int idx,int len,int &newidx){
  newidx = (idx+L-len)%L;
  while(newidx != idx){
    if(!pos[newidx]){
      (newidx+=len)%=L;
      return false;
    }else{
      newidx = (newidx+L-len)%L;
    }
  }
  while(newidx - L > 0){
    newidx -= L;
  }
  printf("%d\n",newidx);
  return true;
}

int main(){
  usefile();
  // 同步增长,冲突取前,倍增 其余删除(因为保证最小)
  scanf("%d",&L);
  while(sz<L){
    scanf("%s",s+sz);
    sz+=strlen(s+sz);
  }
  char minch = s[0];
  rep(i,1,L){
    minch = min(minch,s[i]);
  }
  rep(i,0,L){
    if(s[i] == minch){
      p.push_back(i);
      pos[i]=true;
    }
  }
  int l = 1;
  while(p.size() > 1){
    int state = 0; // 0 for +1, 1 for *2
    minch = s[(p[0]+l)%L];
    for(auto idx : p){
      if(pos[(idx+l)%L] == true){
        state = 1;
        break;
      }
      minch = min(minch,s[(idx+l)%L]);
    }
    if(state == 0){
      q.clear();
      for(auto idx:p){
        if(!pos[idx])continue;
        if(s[(idx+l)%L] == minch){
          q.push_back(idx);
        }else{
          pos[idx]=false;
        }
      }
      p=q;
      l++;
    }else{
      q.clear();
      int startidx ;
      int ret = circle(p[0],l,startidx);
      if(ret){
        return 0;
      }
      int pidx = 0;
      for(pidx=0;pidx<p.size();pidx++){
        if(p[pidx] == startidx){
          break;
        }
      }
      rep(i,pidx,p.size()){
        int idx = p[i];
        if(!pos[idx])continue;
        if(pos[(idx+l)%L]){
          q.push_back(idx);
          pos[(idx+l)%L] = false;
        }else{
          pos[idx]=false;
        }
      }
      rep(i,0,pidx){
        int idx = p[i];
        if(!pos[idx])continue;
        if(pos[(idx+l)%L]){
          q.push_back(idx);
          pos[(idx+l)%L] = false;
        }else{
          pos[idx]=false;
        }
      }
      p=q;
      l*=2;
    }
  }
  printf("%d\n",p[0]);
  return 0;
}

Twofive

Subject to the effect

ion 2001

A到YConfiguration arranged to meet these 25letters are aligned 5*5per row after matrix, monotonically increasing, for the legitimate

All legal arrangement, according to the dictionary sort order

Write a lexicographic converted to strings and string ID is lexicographically number reverse procedure

Try thinking

Look at the amount of data, I can not reckon on the actual size so the first to write a play table, (the upper bound is 25!but there is a limit so I do not know whether it will reduce the

#include <bits/stdc++.h>
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)

using namespace std;

const string filename = "twofive";

void usefile(){
  freopen((filename+".in").c_str(),"r",stdin);
  freopen((filename+".out").c_str(),"w",stdout);
}

int chars[30];
int vis[30];
int cnt = 0;

void print(){
  cout<<endl;
  rep(i,0,5){
    rep(j,0,5){
      cout<<char(chars[i*5+j]+'a')<<" ";
    }
    cout<<endl;
  }
}

void gen(int idx){
  if(idx%5==0){
    rep(i,0,25){
      if(vis[i] == 0){
        vis[i]=1;
        chars[idx] = i;
        gen(idx+1);
        vis[i]=0;
        return ;
      }
    }
  }
  if(idx == 24){
    cnt++;
    chars[24]=24;
    print();
    return ;
  }
  int sti = chars[idx-1];
  if(idx>5){
    sti=min(sti,chars[idx-5]);
  }

  rep(i,sti+1,26-(5-idx%5)*(5-idx/5)){
    if(vis[i])continue;
    vis[i]=1;
    chars[idx] = i;
    gen(idx+1);
    vis[i]=0;
  }
}


int main(){
  // usefile();
  gen(0);
  cout<<cnt<<endl;

  return 0;
}

Run a bit about

7951237
a b c d e 
f g h l n 
i m k q w 
j p o r u 
s t v x y 

Changes only to the above idescribed order of magnitude, can not expect to hit the table

Next, we note that if we have a way to convert from a digital number corresponding to the word, you can find the corresponding word 2 points system

Similarly, if we find the word mapped to the number of methods, then two points (if you can, because this word did not seem half so good to do) can turn to find the numbers, so the analysis, any problem can be solved a corresponding

The idea is also a simple sorting, counting the number is deleted, then the ordered sequence = Total - it is smaller than the number of deleted

answer

Memory of + dp

If we fill in the number of small to large

So obviously, the end of the row number of the newly inserted row number has been inserted at the end of the number, also has been inserted, such as

a b e
c d f
g
h
i

jInsertable position g右侧ore右侧

So we have dp

dp[i0][i1][i2][i3][i4]The first row represents 0 i0th, 1 row i1number ... first i4case the number of rows, the number of remaining unfilled portion of the desired

Regardless of the particular, considering only the fundamental limitation of the subject, the satisfied ij >= i(j+1), because we put the order number, the number is not less than the upper row the next row

There transfer equation

dp[i0][i1][i2][i3][i4] = dp[i0-1][...]+dp[...][i1-1][...]+dp[...][i2-1][...]+dp[...][i3-1][...]+dp[...][i4-1]

Wherein if -1not satisfied row when the magnitude relation between the number, then the corresponding directly dp0

In summary, we have no specific requirements in value can be calculated dp satisfy all topic under restrictions, 时间复杂度 = O(空间*状态转移)=O(6^5*5)and spaceO(6^5)

Solving

The next question is how to seek conversion

Because idx are asking for the actual legal order twofive dictionary

Then we can approach by bit,//延伸阅读 BROP的按位枚举攻击方法

Suppose we are seeking

ADEFGBHIJKC...Y, Then its lexicographical = AB...的所有+ AC...的所有+ ...

Simply put, if the prefix is ​​a prefix length is less than the other requirements, then the number prefix plus all,

Etc. If the length of prefix value equal to the required prefix, the prefix length +

Prefix length for the outer layer, an intermediate for the letters, the time complexity is less than O(25*25)

Above we can be converted from a string to index

in contrast

The same method of approximation, it is possible O(25*25)within the time complexity index into a string

#include <bits/stdc++.h>
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)

using namespace std;

const string filename = "twofive";

void usefile(){
  freopen((filename+".in").c_str(),"r",stdin);
  freopen((filename+".out").c_str(),"w",stdout);
}

char s[100]; // 按位逼近的
char str[100]; // str2index

int dp[6][6][6][6][6];

int dfs(int a=0, int b=0, int c=0, int d=0, int e=0, char ch='A') {
  if(ch > 'Y') return 1;
  int &ret = dp[a][b][c][d][e];
  if(ret) return ret;
  // 每一行 一定小于等于上一行
  int w = 5;
  int *v[6]={&w,&a,&b,&c,&d,&e};
  rep(i,1,6){
    // 未填过 和 已经填过(按照 字母顺序扩展)
    int idx = *v[i]+(i-1)*5;
    if(*v[i] < *v[i-1] && (s[idx] == 0 || s[idx] == ch)){
      (*v[i])++;
      ret+=dfs(a,b,c,d,e,ch+1);
      (*v[i])--;
    }
  }
  return ret;
}

void index2word(){
  int n;
  scanf("%d",&n);
  rep(i,0,25){
    for(s[i] = 'A';; s[i]++) { // 按位逼近 时间复杂度25×25
      memset(dp, 0,sizeof(dp));
      int ret = dfs();
      // cout<<i<<" = "<<s[i]<<"\tret = "<<ret<<endl;
      if(ret >= n) break;
      n -= ret;
    }
  }
  printf("%s\n", s);
}

void word2index(){
  scanf("%s", str);
  int ans = 1;
  rep(i, 0, 25)  {
    for(s[i] = 'A'; s[i] < str[i]; s[i]++) {
      memset(dp, 0,sizeof(dp));
      ans += dfs();
    }
  }
  printf("%d\n", ans);
}

int main(){
  usefile();
  char c;
  cin >> c;
  if(c == 'N')  { // index 2 word
    index2word();
  } else if(c == 'W')  { // word 2 index
    word2index();
  }
  return 0;
}

Dp The above process is implemented in alphabetical order filled by ch guaranteed, so that the outermost dp enumeration time, it directly from the A to the Y

Guess you like

Origin www.cnblogs.com/CroMarmot/p/11080472.html
5.5