Vous êtes sur la page 1sur 13

Strictly not a Prime

There are two tasks involved in solving this problem,

1. Precomputing all "Strictly not a Primes"

2. Processing each query

<1> can be done by bruteforce

Checking if a number is "Strictly not a Prime" or not involves considering all subsequences of the number.

One can generate all subsequences of a number containing N digits by considering the binary representations of the

numbers from 1 to 2^N-1

So the trick is to run a loop from 1 to 2^N-1. Then, in each iteration check index variables's bits(1 bits) to decide

which digits to consider as a part of the subsequence.

For eg,

Let the given number be

12345678

5 has a binary representation of 00000101

So 5 can represent the subsequence 6,8 (Though while implementing you consider the representation backwards i.e

5 represents 1, 3)

Now simply check if 68 is a prime.

A prime sieve can be imlemented to check numbers for being prime.

One simple optimization that can be applied to this process is that if any of the digits of the number being tested is 2,

3, 5, or 7 then it's all subsequences needn't be checked.

If a number is found to be "Strictly not a Prime" you can mark it in an array like IS_SNAP[n] = 1 ( IS_SNAP[for all

n] = 0 initially )

<2> can be done in O(1)

Each query can be processed in O(1) after some precomputation.

One can maintain a table COUNT[n] which gives the total count of the required numbers between 1 to N

calculating COUNT[n] involves a simple recurrence i.e

COUNT[n] = COUNT[n-1] + IS_SNAP[n]

Total count of required integers in a range can be obtained as COUNT[end]-COUNT[start-1]

A particular point to note is that, its not mentioned in the problem statement that, A <= B is always true, so before

calculating the answer one needs to swap A and B if A > B

divyanshu's solution submitted during the contest implements all these ideas,

http://www.spoj.pl/MAIN11/files/src/5518159/

Re-Arrange II

This can be solved using dynamic programming over subsets approach.

Let,

Array A[0...N-1] contain the given numbers.

A subset of the given numbers can be represented by an integer "mask" in the sense that if the ith bit is set in binary

representation of mask then A[i] is included in the set which mask represents.

Let,

F[ mask ][ i ] = minimum P for a set of integers(which do not include A[i]) represented by mask followed by A[i].

Then,

F[ mask ][ i ] = 0 if set represented by mask contains no elements i.e mask equals 0

else

minimum of all abs(A[i]-a[k]) * C[no. of elements in mask set i.e no. of on bits in mask] +

F[ mask&~(1<<k) ][ k ] for all k, such that the kth bit if 1 in the binary representation of mask

Note that, mask&~(1<<k) represents the operation of removing the A[k] from the set represented by mask

Intended complexity was O(2^n * n).

Solution : http://ideone.com/jf99v

Special string

Check out the topcoder editorial for this,

See problem Forbidden Strings

http://community.topcoder.com/tc?module=Static&d1=match_editorials&d2=srm412

Trip

Basically what the problems asks is, print all distinct lcs of the given two strings in lexicographical order

This can be done in two steps,

1. Compute the dp[][] table using dynamic programming as in the original lcs problem.

2. Backtracking through the table to print all distinct lcs

Some tricks may be applied while backtracking through the table.

Since we need to print the lcs's in lexicograhic order so while contructing solution from dp table we can do the following

things,

If we are at a state dp[i][j],

for (char k='a'; k<='z'; k++) { // use k as the first letter

int x = /* first position in first string (from i onwards) that is a k */

int y = /* first position in second string (from j onwards) that is a k */

if (/* x and y both exist*/) {

if (lcs[x][y] == lcs[i][j] - 1) { // make sure we can get a solution of the right length

backtrack to state dp[x][y]

For the lines,

int x = /* first position in first string (from i onwards) that is a k */

int y = /* first position in second string (from j onwards) that is a k */

another precomputation can be done using DP,

Have a look at this tutorial which discusses all the above ideas,

http://www.codechef.com/wiki/tutorial-lcs-problem-revisited

Check out Vaibhav Mittal's solution during the contest which implements all the ideas,

http://www.spoj.pl/MAIN11/files/src/5517814/

SPOJ-KGSS

Lets cut to the chase, the question requires us to use segment trees for RMQ. So if u do not know how to use segment

trees for Range Minimum (maximum for this question) Query, here's the link to get started

http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=lowestCommonAncestor

I tried to solve it using sparse table first but got TLE so dont waste time on solving with other methods.

Now there are two approaches to solve using SegTrees.

1) Inefficient but will get AC-

Make a tree whose nodes save just the index of maximum number in the node's range. Initialise the tree with the array

given. For queries, we need first two largest numbers in the given range. So first find the index of the largest number in the

range <x,y>, say p is that index. Then find the index of the second largest number using two queries, first in <x,p-1> ,

second in <p+1,y>. The max of the two would be the second largest number.

The update function I used is

void update(int node, int b, int e, int i,int v)

if(b==e)

ar[i]=v;

m[node]=b;

return ;

int mid=(b+e)/2;

if(i<=mid)

update(2*node,b,mid,i,v);

else

update(2*node+1,mid+1,e,i,v);

if(ar[m[2*node]]>ar[m[2*node+1]])

m[node]=m[2*node];

else

m[node]=m[2*node+1];

2) Efficient-

Make the tree with nodes having not just the index of largest number but also the maxsum which we need to find. This will

allow us to make only one query. In the update function, the nodes will save maxsum somewhat like this

struct node{

int sum,mx;

};

...

tree[node].sum = max(max(tree[2*node].sum, tree[2*node+1].sum), tree[2*node].mx+tree[2*node+1].mx);

For the leaf nodes(begin==end), put this sum= -1;

ICODER

It should be clear that adding any number to Register R and then taking MOD(65536), will not affect the number of values

that can be obtained. Try with some values if you are not sure.

The no of values will be affected only by MUL.

MUL X

R=(R * X)MOD(65536)

65536=2^16

Let X=(2^a)*y where y is some odd number.

Two cases

1) a<=16, then R=(R*y)MOD(2^(16-a)). Maximum values which we can obtain are 2^(16-a).

2)a>16, then only one value can be obtained.

Vous aimerez peut-être aussi